46 #define COLOUR_STACK_SIZE 18 49 #define TRANSPARENT_COLOUR OFFSET_TRANS 51 #define TRANSPARENT_COLOUR 0 55 #define U_CTRL_NULL 0x00 79 #define U_CTRL_FS 0x1C 80 #define U_CTRL_GS 0x1D 81 #define U_CTRL_RS 0x1E 82 #define U_CTRL_US 0x1F 85 #define UNICODE_SPACE (' ') 86 #define UNICODE_TAB ('\t') 87 #define UNICODE_LF (0x0a) 88 #define UNICODE_CR (0x0d) 89 #define UNICODE_ESC (0x1b) 90 #define UNICODE_HARD_SPACE (0xa0) 91 #define UNICODE_FIGURE_SPACE (0x2007) 92 #define UNICODE_APOSTROPHE_N (0x0149) 93 #define UNICODE_HYPER_ANCHOR_START (0x41) 94 #define UNICODE_HYPER_ANCHOR_END (0x61) 95 #define UNICODE_TEXT_COLOUR_START (0x43) 96 #define UNICODE_TEXT_COLOUR_END (0x63) 97 #define UNICODE_HYPER_ATTRIB_START (0x44) 98 #define UNICODE_HYPER_ATTRIB_END (0x64) 103 #define GLYPH_NDX(x) (x - 30) 106 #define MAX_NUM_LINES 32 107 #define MAX_NUM_CHARS 64 109 #define PNTS_LS_LEN(tls) ((tls + 255) >> 8) 110 #define MTRC_POSN(mll, tls, mr, fsz) mll + (PNTS_LS_LEN(tls) * mr) / fsz 114 #define S_METRIC_POSITION(pp) MTRC_POSN(pp.metric_line_length, pp.total_letter_space, pp.metric_resn, pp.pnts_font_size) 116 #define S_POINTS_POSITION(pp) PNTS_LS_LEN(pp.total_letter_space) + ((pp.metric_line_length * pp.pnts_font_size + pp.metric_resn - 1) / pp.metric_resn) 118 #define S_SPIXEL_POSITION(pp) (((((S_POINTS_POSITION(pp)) * 45) + pp.pixel_par_x - 1) / pp.pixel_par_x) + pp.spxl_tab_start) 122 #define P_PNTS_2_SPXL(pp, pts) ((((pts) * 45) + pp->pixel_par_x - 1) / pp->pixel_par_x) 123 #define P_MTRC_2_PNTS(pp, mtr) ((mtr) * pp->pnts_font_size + pp->metric_resn - 1) / pp->metric_resn 124 #define P_MTRC_2_SPXL(pp, mtr) P_PNTS_2_SPXL(pp, P_MTRC_2_PNTS(pp, mtr)) 126 #define P_METRIC_POSITION(pp) MTRC_POSN(pp->metric_line_length, pp->total_letter_space, pp->metric_resn, pp->pnts_font_size) 128 #define P_POINTS_POSITION(pp) PNTS_LS_LEN(pp->total_letter_space) + ((pp->metric_line_length * pp->pnts_font_size + pp->metric_resn - 1) / pp->metric_resn) 130 #define P_SPIXEL_POSITION(pp) (((((P_POINTS_POSITION(pp)) * 45) + pp->pixel_par_x - 1) / pp->pixel_par_x) + pp->spxl_tab_start) 146 S32BIT real_position;
147 S32BIT mtrc_position;
169 S32BIT hpxl_last_tab,
191 U16BIT spxl_box_width,
208 static void traceLine(
LineLimit *pLine,
CharData *chars, U32BIT f_size, U32BIT m_res )
216 for (nx = pLine->start_ndx, pch = str; nx != pLine->end_ndx && pch != str + 79; nx++, pch++)
218 *pch = (char)chars[nx].uni_chr;
221 DBG_PRINTF(
"Line %d: start=%ld width=%d start=%d end=%d F-Size=%d M-Res=%d\n",
222 pLine->line_num, pLine->position, pLine->l_width, pLine->start_ndx, pLine->end_ndx, f_size, m_res );
223 DBG_PRINTF(
"%s\n", str);
224 nx = pLine->start_ndx;
226 while (nx != pLine->end_ndx)
229 mposn = p_chr->mtrc_position + p_chr->mtrc_advance;
230 sposn = ((mposn * f_size) + m_res - 1) / m_res;
231 sposn = ((sposn * 45) + 55) / 56;
232 DBG_PRINTF(
"(%c,%ld,%d,%d,%d) ", p_chr->uni_chr, p_chr->real_position - pLine->position, p_chr->width, mposn, sposn);
243 static void trace_lines( U16BIT total,
LineLimit *lines,
CharData *chars, U32BIT f_size, U32BIT m_res )
246 while (line_num != total)
248 if (line_num == lines->line_num)
250 traceLine( lines, chars, f_size, m_res );
267 static U16BIT ProcessMarkup( U16BIT *data, OSDColor *cStack, U8BIT *cCount,
pHyperAttribs ha )
269 U16BIT mu_length = 0;
270 if ((*data <= 0x5e) && (*data >= 0x40))
272 mu_length = data[1] + 1;
276 case UNICODE_HYPER_ANCHOR_START:
277 if ((ha != NULL) && (*cCount < COLOUR_STACK_SIZE))
279 ha->number_of_links++;
280 if (ha->markup_state == 0)
282 ha->markup_state = 2;
288 ha->save_colour = *cCount;
291 if (ha->focus_position == ha->number_of_links)
293 cStack[*cCount] = ha->active_colour;
297 cStack[*cCount] = ha->link_colour;
302 case UNICODE_TEXT_COLOUR_START:
303 if ((mu_length == 5) && (*cCount < COLOUR_STACK_SIZE))
306 cStack[++(*cCount)] = RGBT( data[2], data[3], data[4], data[5] );
310 case UNICODE_HYPER_ATTRIB_START:
311 if ((ha != NULL) && (mu_length > 1) && (ha->markup_state == 0))
313 U16BIT mu_lft = mu_length - 2;
314 U16BIT mu_ind = data[2];
317 ha->anchor_wrap = TRUE;
321 ha->anchor_wrap = FALSE;
324 if ((mu_ind & 0x40) && (mu_lft > 3))
326 ha->link_colour = RGBT( data[0], data[1], data[2], data[3] );
330 if ((mu_ind & 0x20) && (mu_lft > 3))
332 ha->active_colour = RGBT( data[0], data[1], data[2], data[3] );
336 if ((mu_ind & 0x10) && (mu_lft > 3))
338 ha->visit_colour = RGBT( data[0], data[1], data[2], data[3] );
343 case UNICODE_HYPER_ANCHOR_END:
344 if ((ha != NULL) && (ha->markup_state > 1))
347 *cCount = ha->save_colour;
351 case UNICODE_TEXT_COLOUR_END:
352 if ((ha != NULL) && (ha->markup_state > 1))
364 case UNICODE_HYPER_ATTRIB_END:
368 if ((ha != NULL) && (ha->markup_state == 0))
370 ha->markup_state = 1;
382 U32BIT fsz = pp->pnts_font_size;
383 switch (pp->glyph_last)
386 if (pp->glyph_index == GLYPH_NDX(
't'))
408 U32BIT fsz = pp->pnts_font_size;
409 switch (pp->glyph_last)
412 switch (pp->glyph_index)
430 if (pp->glyph_index == GLYPH_NDX(
'e'))
438 switch (pp->glyph_index)
442 pp->hpxl_pen_posn -= 2;
457 if (pp->glyph_index == GLYPH_NDX(
't'))
466 else if ((pp->glyph_index == GLYPH_NDX(
'i')) ||
467 (pp->glyph_index == GLYPH_NDX(
'l')))
478 if ((pp->glyph_index == GLYPH_NDX(
'f')) ||
479 (pp->glyph_index == GLYPH_NDX(
't'))
490 if (pp->glyph_index == GLYPH_NDX(
'k'))
498 switch (pp->glyph_index)
518 if (pp->glyph_index == GLYPH_NDX(
'D'))
526 switch (pp->glyph_index)
541 if (pp->glyph_index == GLYPH_NDX(
't'))
549 if (pp->glyph_index == GLYPH_NDX(
'n'))
557 if (pp->glyph_index == GLYPH_NDX(
'a') && (fsz == 31))
566 if (pp->glyph_index == GLYPH_NDX(
'h'))
579 static void AddLetterSpace(
S_PROPERTIES *pp, S32BIT tls)
581 pp->total_letter_space += tls;
582 if (pp->total_letter_space > 0)
584 tls = ((pp->m_to_pix_mlt * pp->total_letter_space) + (pp->m_to_pix_div - 1)) / pp->m_to_pix_div;
586 tls = (tls + 255) / 256;
590 tls = ((pp->m_to_pix_mlt * pp->total_letter_space) - (pp->m_to_pix_div - 1)) / pp->m_to_pix_div;
591 tls = (tls - 255) / 256;
593 if (pp->hpxl_letter_offset != tls)
595 pp->hpxl_pen_posn += tls - pp->hpxl_letter_offset;
596 pp->hpxl_letter_offset = tls;
609 if (pp->glyph_last && attrib->letter_space)
611 AddLetterSpace(pp,attrib->letter_space);
614 if (ftd_ptr->face_type == FTYPE_PFR)
616 if (FT_Get_PFR_Kerning(ftd_ptr->face, pp->glyph_last, pp->glyph_index, &kerning) == 0 &&
619 pp->metric_line_length += kerning.x;
620 kerning.x *= pp->m_to_pix_mlt * pp->pnts_font_size;
621 kerning.y = ftd_ptr->metric_resolution * pp->m_to_pix_div;
624 kerning.x -= kerning.y >> 1;
628 kerning.x += kerning.y >> 2;
630 pp->hpxl_pen_posn += kerning.x / kerning.y;
633 else if (pp->glyph_last != 0)
635 if (pp->glyph_last != ftd_ptr->glyph_ndx_space)
637 if (FT_Get_Kerning(ftd_ptr->face, pp->glyph_last, pp->glyph_index, FT_KERNING_UNSCALED, &kerning) == 0)
642 pp->metric_line_length += kerning.x;
643 kerning.x *= pp->m_to_pix_mlt * pp->pnts_font_size;
644 kerning.y = ftd_ptr->metric_resolution * pp->m_to_pix_div;
647 kerning.x -= kerning.y >> 1;
651 kerning.x += kerning.y >> 2;
653 pp->hpxl_pen_posn += kerning.x / kerning.y;
660 if (pp->font_style == 0 &&
661 pp->font_index == BUILT_IN_FONT)
663 if (mg_hd_mode == NORMAL_SD)
668 pp->glyph_last = pp->glyph_index;
679 FT_Face the_face = ftd_ptr->face;
683 if (ftd_ptr->current_fnt_id != f_sz_data->fnt_id)
685 if (FT_Set_Char_Size( the_face, f_sz_data->width, f_sz_data->height, 72, 72 ) != 0)
687 TRACE(TERROR, (
"FT_Set_Char_Size FAILED: w=%u, h=%u\n", f_sz_data->width, f_sz_data->height))
690 ftd_ptr->current_fnt_id = f_sz_data->fnt_id;
692 if (char_data->mtrc_advance == 0)
694 if (ftd_ptr->face_type == FTYPE_PFR)
698 if (FT_Get_PFR_Advance( the_face, pp->glyph_index, &advance ) != 0)
700 TRACE(TERROR, (
"FT_Get_PFR_Advance FAILED: gi=%u\n", pp->glyph_index))
705 char_data->mtrc_advance = (S16BIT)advance;
710 if (FT_Load_Glyph( the_face, pp->glyph_index, FT_LOAD_NO_SCALE ) != 0)
712 TRACE(TERROR, (
"FT_Load_Glyph FAILED: gi=%u\n", pp->glyph_index))
717 char_data->mtrc_advance = (S16BIT)the_face->glyph->metrics.horiAdvance;
722 load_flags = FT_LOAD_RENDER;
731 if (u_chr == 0x00e3 || u_chr == 0x00f1 || u_chr == 0x00f5)
733 load_flags |= FT_LOAD_NO_AUTOHINT;
735 if (FT_Load_Glyph( the_face, pp->glyph_index, load_flags ) != 0)
740 char_data->uni_chr = u_chr;
741 char_data->gf_ndx = pp->glyph_index;
742 char_data->width = the_face->glyph->bitmap.width;
743 pp->char_left = the_face->glyph->bitmap_left;
747 if (ftd_ptr->font_ndx != BUILT_IN_FONT)
749 pp->char_adv = (S8BIT)((the_face->glyph->linearHoriAdvance + 0x7fff) >> 16);
761 pp->char_adv = f_sz_data->figure_adv;
766 if ((the_face->glyph->linearHoriAdvance & 0x8000) &&
767 (ftd_ptr->current_fnt_id & 0xff) == 24 && pp->hpxl_last_tab == pp->hpxl_pen_posn)
771 pp->char_adv = (S8BIT)(the_face->glyph->linearHoriAdvance >> 16);
775 pp->char_adv = (S8BIT)((the_face->glyph->linearHoriAdvance + 0x7fff) >> 16);
788 pp->hpxl_line_end = 0;
789 pp->font_style = (U8BIT)((f_sz_data->fnt_id >> 8) & 0xFF);
790 if (pp->font_style & FONT_STYLE_NO_SCALE)
792 pp->m_to_pix_mlt = 1;
793 pp->m_to_pix_div = 1;
794 pp->pixel_par_x = 45;
796 else if ((pp->font_style & FONT_STYLE_SQUARE) && (mg_hd_mode != NORMAL_SD))
798 pp->m_to_pix_mlt = mg_ctxt.osd_y.mlt;
799 pp->m_to_pix_div = mg_ctxt.osd_y.div;
800 pp->pixel_par_x = 64;
804 pp->m_to_pix_mlt = mg_ctxt.osd_x.mlt * 9;
805 pp->m_to_pix_div = mg_ctxt.osd_y.div * 14;
806 pp->pixel_par_x = 56;
808 if ((attrib->justify & JFY_HZ_MASK) == JUSTIFY_H_START)
810 pp->hpxl_last_tab = f_sz_data->bound_box.left;
811 pp->pnts_tab_start = f_sz_data->pnts_xleftoffset;
812 pp->spxl_tab_start = f_sz_data->spxl_xleftoffset;
816 pp->hpxl_last_tab = 0;
817 pp->spxl_tab_start = 0;
819 pp->hpxl_pen_posn = pp->hpxl_last_tab;
820 pp->hpxl_letter_offset = 0;
821 pp->total_letter_space = 0;
822 pp->metric_line_length = 0;
823 pp->metric_break_length = 0;
824 pp->pnts_font_size = (S32BIT)f_sz_data->fnt_id & 0xFF;
825 pp->font_index = f_sz_data->fnt_id >> 16;
838 new_posn = P_SPIXEL_POSITION(pp) + pp->p_font_size->spxl_xleftoffset;
841 if ((new_posn % 45) != 0)
843 new_posn += 45 - (new_posn % 45);
845 pp->spxl_tab_start = new_posn;
847 pp->metric_line_length = 0;
848 pp->hpxl_letter_offset = 0;
849 pp->total_letter_space = 0;
851 new_posn = ((new_posn * mg_ctxt.osd_x.mlt) + (mg_ctxt.osd_x.div >> 1)) / mg_ctxt.osd_x.div;
852 pp->hpxl_pen_posn = pp->p_current_line->position + new_posn;
853 pp->hpxl_last_tab = pp->hpxl_pen_posn;
864 FT_UInt mt_adv, S8BIT pxl_adv )
866 if (pp->glyph_last && attrib->letter_space)
868 AddLetterSpace(pp,attrib->letter_space);
869 if (pp->hpxl_pen_posn < pp->p_current_line->position)
871 pp->p_current_line->position = pp->hpxl_pen_posn;
874 if ((attrib->justify & JFY_HZ_MASK) == JUSTIFY_H_CENTRE)
876 char_data->mtrc_position = P_METRIC_POSITION(pp);
877 char_data->mtrc_advance = mt_adv;
878 char_data->real_position = pp->hpxl_pen_posn;
879 char_data->colour = TRANSPARENT_COLOUR;
880 char_data->width = pxl_adv;
882 pp->hpxl_pen_posn += pxl_adv;
883 pp->metric_line_length += mt_adv;
892 static void MinorAdjustOfPenPositionAtSpace(
S_PROPERTIES *pp )
895 psn = P_POINTS_POSITION(pp);
896 tmp = ((pp->m_to_pix_mlt * psn) + (pp->m_to_pix_div >> 1)) / pp->m_to_pix_div;
897 tmp += pp->hpxl_last_tab;
898 if (tmp != pp->hpxl_pen_posn)
900 TPRINT(TTEXT, (
"MAPP(%d,%d,%d,%d,%d)", pp->total_letter_space, pp->metric_line_length, psn, tmp, pp->hpxl_pen_posn));
901 pp->hpxl_pen_posn += (tmp - pp->hpxl_pen_posn) / 2;
915 S32BIT brk_posn, ndx;
916 pp->metric_line_length -= pp->metric_break_length;
917 brk_posn = MTRC_POSN(pp->metric_break_length, pp->break_letter_space, pp->metric_resn, pp->pnts_font_size);
918 TRACE(TTEXT, (
"Metric break-posn=%d; After: start=%d 1st-char=0x%x", brk_posn, pp->break_line.start_ndx, chars[pp->break_line.start_ndx].uni_chr))
921 assert( pp->break_line.start_ndx < cur_ndx );
922 for (ndx = pp->break_line.start_ndx; ndx != cur_ndx; ndx++)
924 assert( chars[ndx].mtrc_position >= brk_posn );
925 chars[ndx].mtrc_position -= brk_posn;
928 pp->metric_break_length = 0;
929 pp->break_letter_space = 0;
941 CharData *p_start, *p_other, *p_last;
943 S32BIT fudge_size, fudge_last;
945 assert(line->end_ndx > line->start_ndx);
946 p_start = chars + line->start_ndx;
947 p_last = chars + line->end_ndx - 1;
948 assert(line->position <= p_start->real_position);
951 fudge_size = p_last->real_position + p_last->width - line->position;
954 if (fudge_size > pp->hpxl_box_width && p_start != p_last)
957 fudge_size -= pp->hpxl_box_width;
958 if (line->position < p_start->real_position)
971 p_last->real_position -= fudge_size;
975 fudge_last = fudge_size;
976 p_other = p_last - 1;
978 while (p_other != p_start)
980 p_other->real_position -= fudge_size;
981 if (p_other->real_position + p_other->width + 1 < p_last->real_position)
986 p_other->real_position++;
995 assert(p_other == p_start);
996 TRACE(TTEXT, (
"More fudging to do %d", fudge_size))
998 p_last = chars + line->end_ndx - 1;
1000 while (p_other != p_last)
1002 p_other->real_position += fudge_size;
1003 if (p_start->real_position + p_start->width + 1 < p_other->real_position)
1008 if (fudge_size == 0)
1016 assert(p_other == p_last);
1017 p_start = chars + line->start_ndx;
1019 while (fudge_size != fudge_last);
1020 TRACE(TERROR, (
"fudging failed to complete %d", fudge_size))
1035 S32BIT len, mtr_end, width;
1040 assert(line->end_ndx > line->start_ndx);
1041 ndx = line->end_ndx - 1;
1043 mtr_end = p_cd->mtrc_position + p_cd->mtrc_advance;
1044 width = pp->spxl_box_width - pp->p_font_size->spxl_xleftoffset;
1046 ndx = line->start_ndx;
1049 while (ndx != line->end_ndx)
1051 len = P_MTRC_2_SPXL(pp, mtr_end - p_cd->mtrc_position);
1059 assert(ndx <= line->end_ndx);
1060 line->start_ndx = ndx;
1063 line->l_width -= p_cd->real_position - line->position;
1064 line->position = p_cd->real_position;
1077 S32BIT mleft, mhalf, rright, mright, b_wdth;
1080 U16BIT e_ndx, s_ndx;
1082 assert(line->end_ndx > line->start_ndx);
1083 e_ndx = line->end_ndx - 1;
1084 s_ndx = line->start_ndx;
1085 p_ecd = chars + e_ndx;
1086 if (justify & WRAP_WORDS)
1089 while (e_ndx != s_ndx && p_ecd->uni_chr == UNICODE_SPACE)
1095 mright = p_ecd->mtrc_position + p_ecd->mtrc_advance;
1096 p_scd = chars + s_ndx;
1097 mleft = p_scd->mtrc_position;
1098 rright = pp->break_line.position;
1100 #ifdef ACCURATE_CENTRE_TRUNCATION 1102 mhalf = mright >> 1;
1103 b_wdth = pp->spxl_box_width - pp->p_font_size->spxl_xleftoffset;
1104 while ((e_ndx != s_ndx) && (P_MTRC_2_SPXL(pp, mright - mleft) > b_wdth))
1106 if (mright - mhalf > mhalf - mleft)
1108 rright = p_ecd->real_position;
1111 mright = p_ecd->mtrc_position + p_ecd->mtrc_advance;
1117 mleft = p_scd->mtrc_position;
1123 mhalf = mright << 1;
1124 b_wdth = pp->spxl_box_width;
1125 while ((e_ndx != s_ndx) && (P_MTRC_2_SPXL(pp, mhalf - mright) > b_wdth))
1127 rright = p_ecd->real_position;
1130 mhalf = (p_ecd->mtrc_position + p_ecd->mtrc_advance) << 1;
1132 b_wdth -= pp->p_font_size->spxl_xleftoffset;
1133 while ((e_ndx != s_ndx) && (P_MTRC_2_SPXL(pp, mright - mleft) > b_wdth))
1137 mleft = p_scd->mtrc_position << 1;
1142 if (s_ndx != line->start_ndx || e_ndx != (line->end_ndx - 1))
1144 assert( rright > p_scd->real_position );
1145 if (rright > p_scd->real_position)
1147 assert(s_ndx <= (e_ndx + 1));
1148 line->start_ndx = s_ndx;
1149 line->end_ndx = e_ndx + 1;
1152 line->position = p_scd->real_position;
1153 line->l_width = p_ecd->real_position + p_ecd->width - p_scd->real_position;
1165 TRACE(TTEXT, (
"start=%d bk-end=%d", pp->p_current_line->start_ndx, pp->break_line.end_ndx))
1166 if (pp->p_current_line->start_ndx < pp->break_line.end_ndx)
1168 pp->p_current_line->l_width = pp->break_line.l_width;
1169 pp->p_current_line->end_ndx = pp->break_line.end_ndx;
1170 pp->p_current_line->line_num = line_num;
1171 pp->hpxl_last_tab = pp->break_line.position;
1172 switch (justify & JFY_HZ_MASK)
1175 AdjustLineEnding( pp, chars );
1178 case JUSTIFY_H_CENTRE:
1179 AdjustLineMiddle( pp, chars, justify );
1180 FudgeForHD( pp, chars );
1184 FudgeForHD( pp, chars );
1185 pp->spxl_tab_start = f_sz_data->spxl_xleftoffset;
1186 pp->pnts_tab_start = f_sz_data->pnts_xleftoffset;
1187 pp->break_line.position -= f_sz_data->bound_box.left;
1190 pp->hpxl_letter_offset = 0;
1191 pp->total_letter_space = 0;
1192 pp->p_current_line++;
1196 if ((justify & JFY_HZ_MASK) == JUSTIFY_H_START)
1198 pp->break_line.position -= f_sz_data->bound_box.left;
1201 pp->p_current_line->position = pp->break_line.position;
1202 pp->p_current_line->start_ndx = pp->break_line.start_ndx;
1203 pp->break_line.start_ndx = pp->break_line.end_ndx;
1217 while (lines[first].line_num < num)
1223 while (num != MAX_NUM_LINES)
1225 lines[first] = lines[num];
1229 return &lines[first - 1];
1238 OSDColor col, U16BIT caret )
1240 if (f_sz_data->sbit_cache)
1242 CacheSbit *c_sbit = &f_sz_data->sbit_cache[caret - FIRST_CACHE_CHAR];
1243 char_data->width = c_sbit->width;
1244 char_data->real_position = pp->hpxl_pen_posn + c_sbit->left;
1245 char_data->gf_ndx = 0;
1249 FT_Face the_face = ftd_ptr->face;
1250 char_data->gf_ndx = FT_Get_Char_Index( the_face, caret );
1251 if (FT_Load_Glyph( the_face, char_data->gf_ndx, FT_LOAD_RENDER ) == 0)
1253 char_data->width = the_face->glyph->bitmap.width;
1254 char_data->real_position = pp->hpxl_pen_posn + the_face->glyph->bitmap_left;
1257 char_data->mtrc_position = P_METRIC_POSITION(pp);
1258 char_data->mtrc_advance = ftd_ptr->horiz_adv[caret - FIRST_CACHE_CHAR];
1259 char_data->uni_chr = caret;
1260 char_data->colour = col;
1278 S_FontDetails *ftd_ptr, U16BIT hpxl_box_width, U16BIT spxl_box_width,
1282 FT_UInt *hori_advance = ftd_ptr->horiz_adv;
1283 OSDColor colour_stack[COLOUR_STACK_SIZE];
1285 U16BIT u_chr, uni_pos, char_count;
1287 EBreakState break_state;
1288 U8BIT colour_count, hz_justify;
1289 U16BIT spxl_avl_width;
1292 lines[0].position = 0;
1293 lines[0].start_ndx = 0;
1294 lines[0].end_ndx = 0;
1295 prop.break_line.start_ndx = 0;
1299 colour_stack[0] = attrib->fore_colour;
1300 break_state = NO_BREAK;
1301 prop.p_font_size = attrib->font.hdl;
1302 prop.p_current_line = lines;
1303 prop.metric_resn = ftd_ptr->metric_resolution;
1304 prop.hpxl_box_width = hpxl_box_width;
1305 prop.spxl_box_width = spxl_box_width;
1307 InitialiseProperties( attrib, f_sz_data, &prop );
1309 hz_justify = attrib->justify & JFY_HZ_MASK;
1310 if (hz_justify == JUSTIFY_H_START)
1312 spxl_avl_width = spxl_box_width;
1316 spxl_avl_width = spxl_box_width - f_sz_data->spxl_xleftoffset;
1320 for (uni_pos = 0; uni_pos < unistr.len; uni_pos++)
1322 if (uni_pos == attrib->entry_point)
1324 AddCaretChar( &prop, ftd_ptr, f_sz_data, char_data, colour_stack[colour_count], attrib->caret );
1328 u_chr = unistr.data[uni_pos];
1331 case UNICODE_LF:
case U_CTRL_NULL:
1332 case U_CTRL_A:
case U_CTRL_B:
case U_CTRL_C:
case U_CTRL_D:
case U_CTRL_E:
1333 case U_CTRL_F:
case U_CTRL_G:
case U_CTRL_H:
case U_CTRL_K:
case U_CTRL_L:
1334 case U_CTRL_N:
case U_CTRL_O:
case U_CTRL_P:
case U_CTRL_Q:
case U_CTRL_R:
1335 case U_CTRL_S:
case U_CTRL_T:
case U_CTRL_U:
case U_CTRL_V:
case U_CTRL_W:
1336 case U_CTRL_X:
case U_CTRL_Y:
case U_CTRL_Z:
case U_CTRL_FS:
1337 case U_CTRL_GS:
case U_CTRL_RS:
case U_CTRL_US:
1338 TRACE(TTEXT, (
"Ignoring control char 0x%x", u_chr))
1342 prop.break_line.l_width = prop.hpxl_line_end - prop.p_current_line->position;
1343 if (break_state != OVER_RUN)
1345 prop.break_line.end_ndx = char_count;
1347 prop.break_line.position = prop.hpxl_pen_posn;
1348 prop.break_line.start_ndx = char_count;
1349 prop.hpxl_last_tab = prop.hpxl_pen_posn;
1350 if (hz_justify == JUSTIFY_H_START)
1352 prop.pnts_tab_start = f_sz_data->pnts_xleftoffset;
1353 prop.spxl_tab_start = f_sz_data->spxl_xleftoffset;
1355 prop.metric_line_length = 0;
1356 break_state = NEW_LINE;
1362 if (uni_pos != unistr.len)
1364 uni_pos += ProcessMarkup( &unistr.data[uni_pos], colour_stack, &colour_count, attrib->p_ha );
1369 if (hz_justify == JUSTIFY_H_START)
1371 MoveTabPosition( &prop );
1375 u_chr = UNICODE_SPACE;
1378 if (u_chr == UNICODE_SPACE)
1380 AddSpaceRendering( attrib, &prop, char_data, ftd_ptr->space_horiz_adv, f_sz_data->space_adv );
1381 if (hz_justify == JUSTIFY_H_CENTRE)
1385 char_data->gf_ndx = ftd_ptr->glyph_ndx_space;
1386 char_data->uni_chr = u_chr;
1388 char_data->spxl_end = (S16BIT)S_SPIXEL_POSITION(prop);
1393 prop.glyph_last = ftd_ptr->glyph_ndx_space;
1395 if (mg_ctxt.out_osd_width == 720)
1397 MinorAdjustOfPenPositionAtSpace( &prop );
1400 if ((break_state != BREAKING) && (attrib->justify & WRAP_WORDS))
1402 prop.break_line.l_width = prop.hpxl_line_end - prop.p_current_line->position;
1403 if (break_state != OVER_RUN)
1405 prop.break_line.end_ndx = char_count;
1407 if (S_SPIXEL_POSITION(prop) > spxl_avl_width)
1409 TRACE(TTEXT, (
"Need line break: sdp=%ld, aw=%d", S_SPIXEL_POSITION(prop), spxl_avl_width))
1410 prop.break_line.position = prop.hpxl_pen_posn;
1411 prop.break_line.start_ndx = char_count;
1412 prop.metric_line_length = 0;
1413 break_state = NEW_LINE;
1417 break_state = BREAKING;
1420 if (hz_justify == JUSTIFY_H_END)
1422 if (prop.hpxl_pen_posn > prop.hpxl_line_end)
1424 prop.hpxl_line_end = prop.hpxl_pen_posn;
1429 case UNICODE_HARD_SPACE:
1430 AddSpaceRendering( attrib, &prop, char_data, ftd_ptr->space_horiz_adv, f_sz_data->space_adv );
1431 if (hz_justify == JUSTIFY_H_CENTRE)
1435 char_data->gf_ndx = ftd_ptr->glyph_ndx_space;
1436 char_data->uni_chr = u_chr;
1440 prop.glyph_last = ftd_ptr->glyph_ndx_space;
1441 if (prop.hpxl_pen_posn > prop.hpxl_line_end)
1443 prop.hpxl_line_end = prop.hpxl_pen_posn;
1447 case UNICODE_FIGURE_SPACE:
1448 AddSpaceRendering( attrib, &prop, char_data, ftd_ptr->fig_horiz_adv, f_sz_data->figure_adv );
1449 if (hz_justify == JUSTIFY_H_CENTRE)
1453 char_data->gf_ndx = ftd_ptr->glyph_ndx_space;
1454 char_data->uni_chr = u_chr;
1458 prop.glyph_last = ftd_ptr->glyph_ndx_space;
1459 if (prop.hpxl_pen_posn > prop.hpxl_line_end)
1461 prop.hpxl_line_end = prop.hpxl_pen_posn;
1467 if (u_chr < (FIRST_CACHE_CHAR + CHAR_CACHE_SIZE))
1469 assert(u_chr >= FIRST_CACHE_CHAR);
1470 prop.glyph_index = ftd_ptr->glyph_ndx[u_chr - FIRST_CACHE_CHAR];
1472 char_data->mtrc_advance = (S16BIT)hori_advance[u_chr - FIRST_CACHE_CHAR];
1474 if (f_sz_data->sbit_cache)
1476 CacheSbit *c_sbit = &f_sz_data->sbit_cache[u_chr - FIRST_CACHE_CHAR];
1477 char_data->uni_chr = u_chr;
1478 char_data->gf_ndx = 0;
1479 char_data->width = c_sbit->width;
1480 prop.char_left = c_sbit->left;
1481 prop.char_adv = c_sbit->advance;
1485 if (prop.glyph_index == 0 ||
1486 !LoadPrintableChar( ftd_ptr, f_sz_data, &prop, u_chr, char_data ))
1494 prop.glyph_index = FT_Get_Char_Index( ftd_ptr->face, u_chr );
1495 char_data->mtrc_advance = 0;
1496 if (prop.glyph_index == 0 ||
1497 !LoadPrintableChar( ftd_ptr, f_sz_data, &prop, u_chr, char_data ))
1499 TRACE(TTEXT, (
"0x%x is not printable\n", u_chr))
1503 char_data->colour = colour_stack[colour_count];
1505 if (break_state == BREAKING)
1507 prop.break_line.position = prop.hpxl_pen_posn + prop.char_left;
1508 prop.metric_break_length = prop.metric_line_length;
1509 prop.break_letter_space = prop.total_letter_space;
1510 prop.break_line.end_ndx = char_count;
1511 prop.break_line.start_ndx = char_count;
1512 break_state = HAD_BREAK;
1515 DoTheKerning( attrib, ftd_ptr, &prop );
1518 S32BIT tmp_adv = prop.hpxl_pen_posn + prop.char_left;
1519 char_data->real_position = tmp_adv;
1520 if (tmp_adv < prop.p_current_line->position)
1522 prop.p_current_line->position = tmp_adv;
1524 tmp_adv += char_data->width;
1525 if (tmp_adv > prop.hpxl_line_end)
1527 prop.hpxl_line_end = tmp_adv;
1531 prop.hpxl_pen_posn += prop.char_adv;
1532 char_data->mtrc_position = S_METRIC_POSITION(prop);
1533 prop.metric_line_length += char_data->mtrc_advance;
1534 if (prop.hpxl_pen_posn > prop.hpxl_line_end)
1536 prop.hpxl_line_end = prop.hpxl_pen_posn;
1539 char_data->spxl_end = (S16BIT)S_SPIXEL_POSITION(prop);
1544 if (attrib->justify & WRAP_VERTICAL)
1547 prop.break_line.l_width = prop.hpxl_line_end - prop.p_current_line->position;
1548 prop.break_line.end_ndx = char_count;
1549 prop.break_line.position = prop.hpxl_pen_posn;
1550 prop.metric_line_length = 0;
1551 break_state = NEW_LINE;
1555 if (S_SPIXEL_POSITION(prop) > spxl_avl_width)
1558 TRACE(TTEXT, (
"Need line-break: sdp=%ld, aw=%d", S_SPIXEL_POSITION(prop), spxl_avl_width))
1560 if (TTEXT & mheg_trace_debug)
1562 prop.p_current_line->l_width = prop.hpxl_line_end - prop.p_current_line->position;
1563 prop.p_current_line->end_ndx = char_count;
1564 prop.p_current_line->line_num = total_lines;
1565 traceLine( prop.p_current_line, chars, prop.pnts_font_size, prop.metric_resn );
1568 switch (break_state)
1572 prop.break_letter_space += attrib->letter_space;
1573 prop.total_letter_space -= prop.break_letter_space;
1574 ProcessWrappingBreak( &prop, chars, char_count );
1575 break_state = NEW_LINE;
1578 if (hz_justify == JUSTIFY_H_START)
1580 TRACE(TTEXT, (
"Over run at %d", char_count))
1581 assert(break_state == NO_BREAK);
1582 prop.break_line.end_ndx = char_count - 1;
1583 break_state = OVER_RUN;
1593 if (break_state == NEW_LINE)
1595 ProcessNewLine( &prop, chars, f_sz_data, total_lines, attrib->justify );
1599 if ((total_lines == available_lines) &&
1600 ((attrib->justify & JUSTIFY_V_JUSTIFIED) == JUSTIFY_V_START)
1606 if (prop.p_current_line == &lines[MAX_NUM_LINES - 1])
1608 if ((attrib->justify & JUSTIFY_V_JUSTIFIED) != JUSTIFY_V_END)
1610 TRACE(TERROR, (
"Run out of line space"))
1614 prop.p_current_line = ShuffleUpLines( lines, total_lines - available_lines );
1616 prop.glyph_last = 0;
1617 break_state = NO_BREAK;
1621 if (uni_pos == attrib->entry_point)
1624 AddCaretChar( &prop, ftd_ptr, f_sz_data, char_data, colour_stack[colour_count], attrib->caret );
1625 if ((char_data->real_position + char_data->width) > prop.hpxl_line_end)
1627 prop.hpxl_line_end = char_data->real_position + char_data->width;
1632 TRACE(TTEXT, (
"last line: mt=%ld, rt=%ld", prop.metric_line_length, prop.hpxl_line_end))
1633 prop.p_current_line->l_width = prop.hpxl_line_end - prop.p_current_line->position;
1634 prop.p_current_line->line_num = total_lines;
1635 if (break_state == OVER_RUN)
1637 prop.p_current_line->end_ndx = prop.break_line.end_ndx;
1641 prop.p_current_line->end_ndx = char_count;
1642 if (prop.p_current_line->start_ndx < char_count)
1644 prop.break_line.position = prop.hpxl_pen_posn;
1645 switch (attrib->justify & JFY_HZ_MASK)
1648 AdjustLineEnding( &prop, chars );
1651 case JUSTIFY_H_CENTRE:
1652 AdjustLineMiddle( &prop, chars, attrib->justify );
1653 FudgeForHD( &prop, chars );
1657 FudgeForHD( &prop, chars );
1662 if (prop.p_current_line->l_width)
1667 prop.p_current_line++;
1669 prop.p_current_line->line_num = total_lines;
1671 *p_chr_cnt = char_count;
1681 #define TextDrawFn TextDraw8Bit 1682 #define RenderGlyphFn RenderGlyph8Bit 1683 #define TDColor U8BIT 1684 #define MakeTDColor(col) OSD_FindNearestColourIndex( col ) 1685 #define GreyValue(val) (val >> 6) 1686 #define SRC_FORE_MAX 3 1687 #define IsOpaqueColor( tcol ) (tcol >= OFFSET_OPAQUE) 1688 #define NotTransparent( fcol ) ((fcol >> 24) > 0x18) 1689 #define CombineAlphaColour(pixel, grey_val, fc, tc) if (grey_val) pixel = aa_8bit_cols[grey_val]; 1691 #define CalcColorArray(for_col) \ 1692 if ( aa_8bit_cols[3] != for_col) { \ 1693 U8BIT fa, ba, bck_col = aa_8bit_cols[0]; \ 1694 register U32BIT comp, tmp_c, alpha_c; \ 1695 comp = mg_palette[for_col] >> 24; \ 1696 ba = (U8BIT)(mg_palette[bck_col] >> 24); \ 1697 alpha_c = ((((255 ^ ba) * comp) + 382) / 765) + ba; \ 1698 tmp_c = alpha_c << 24; \ 1699 fa = (U8BIT)((comp + 1) / 3); \ 1701 ba = (U8BIT)(((255 ^ fa) * comp) + 127) / 255; \ 1702 comp = ba * ((mg_palette[bck_col] >> 16) & 0xff) + fa * ((mg_palette[for_col] >> 16) & 0xff); \ 1703 tmp_c |= (comp / alpha_c) << 16; \ 1704 comp = ba * ((mg_palette[bck_col] >> 8) & 0xff) + fa * ((mg_palette[for_col] >> 8) & 0xff); \ 1705 tmp_c |= (comp / alpha_c) << 8; \ 1706 comp = ba * (mg_palette[bck_col] & 0xff) + fa * (mg_palette[for_col] & 0xff); \ 1707 tmp_c |= (comp / alpha_c); \ 1708 aa_8bit_cols[1] = OSD_FindNearestColourIndex(tmp_c); \ 1709 comp = 2 * (mg_palette[for_col] >> 24); \ 1710 ba = (U8BIT)(mg_palette[bck_col] >> 24); \ 1711 alpha_c = ((((255 ^ ba) * comp) + 382) / 765) + ba; \ 1712 tmp_c = alpha_c << 24; \ 1713 fa = (U8BIT)((comp + 1) / 3); \ 1715 ba = (U8BIT)(((255 ^ fa) * comp) + 127) / 255; \ 1716 comp = ba * ((mg_palette[bck_col] >> 16) & 0xff) + fa * ((mg_palette[for_col] >> 16) & 0xff); \ 1717 tmp_c |= (comp / alpha_c) << 16; \ 1718 comp = ba * ((mg_palette[bck_col] >> 8) & 0xff) + fa * ((mg_palette[for_col] >> 8) & 0xff); \ 1719 tmp_c |= (comp / alpha_c) << 8; \ 1720 comp = ba * (mg_palette[bck_col] & 0xff) + fa * (mg_palette[for_col] & 0xff); \ 1721 tmp_c |= (comp / alpha_c); \ 1722 aa_8bit_cols[2] = OSD_FindNearestColourIndex(tmp_c); \ 1723 aa_8bit_cols[3] = for_col; \ 1726 static U8BIT aa_8bit_cols[4] = {OFFSET_TRANS, OFFSET_TRANS, OFFSET_TRANS, OFFSET_TRANS};
1731 #undef RenderGlyphFn 1733 #undef CalcColorArray 1737 #undef IsOpaqueColor 1738 #undef NotTransparent 1739 #undef CombineAlphaColour 1750 #define TextDrawFn TextDraw16Bit 1751 #define RenderGlyphFn RenderGlyph16Bit 1752 #define TDColor HD2Color 1753 #define MakeTDColor(col) MakeHD2Color( col ) 1754 #define GreyValue(val) val 1755 #define SRC_FORE_MAX 255 1756 #define IsOpaqueColor( tcol ) ((tcol >> 12) == 0xf) 1757 #define NotTransparent( fcol ) ((fcol >> 28) != 0x0) 1758 #define CombineAlphaColour(pixel, grey_val, full_col, fore_col) \ 1759 grey_val *= (full_col >> 24); \ 1760 if (grey_val & 0xf000) { pixel = (fore_col & 0x0fff) | (grey_val & 0xf000); } 1765 #undef RenderGlyphFn 1766 #undef CombineAlphaColour 1772 #define TextDrawFn TextDraw16BitBlend 1773 #define RenderGlyphFn RenderGlyph16Blend 1774 #define CombineAlphaColour(pixel, grey_val, full_col, fore_col) \ 1775 grey_val *= (full_col >> 24); \ 1776 if (grey_val & 0xff00) { \ 1777 register U32BIT fa, ba, comp, tmp_c, alpha_c; \ 1778 ba = (U8BIT)(pixel >> 12); \ 1780 alpha_c = ((((15 - ba) *grey_val) + 1912) / 3825) + comp; \ 1781 fa = (U8BIT)(grey_val / SRC_FORE_MAX); \ 1782 ba = (((255 ^ fa) *comp) + 127) / 255; \ 1783 tmp_c = (alpha_c / 17) << 12; \ 1784 comp = ba * ((pixel >> 8) & 0xf) + fa * ((fore_col >> 8) & 0xf); \ 1785 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 8; \ 1786 comp = ba * ((pixel >> 4) & 0xf) + fa * ((fore_col >> 4) & 0xf); \ 1787 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 4; \ 1788 comp = ba * (pixel & 0xf) + fa * (fore_col & 0xf); \ 1789 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c); \ 1790 pixel = (U16BIT)tmp_c; \ 1796 #undef RenderGlyphFn 1800 #undef IsOpaqueColor 1801 #undef NotTransparent 1802 #undef CombineAlphaColour 1807 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 1813 #define TextDrawFn TextDraw32Bit 1814 #define RenderGlyphFn RenderGlyph32Bit 1815 #define TDColor OSDColor 1816 #define GreyValue(val) val 1817 #define MakeTDColor(col) AlphaPlatform(col) 1818 #define SRC_FORE_MAX 255 1819 #define IsOpaqueColor( tcol ) ((tcol >> 24) == MAX_ALPHA) 1820 #define NotTransparent( fcol ) ((fcol >> 24) != 0x00) 1821 #define CombineAlphaColour(pixel, grey_val, full_col, fore_col) \ 1822 grey_val *= CalcAlpha(fore_col >> 24); \ 1823 if (grey_val > 127) { pixel = (fore_col & 0xffffff) | ((grey_val << 16) & 0xff000000); } 1828 #undef RenderGlyphFn 1829 #undef CombineAlphaColour 1835 #define TextDrawFn TextDraw32BitBlend 1836 #define RenderGlyphFn RenderGlyph32Blend 1837 #define CombineAlphaColour(pixel, grey_val, full_col, fore_col) \ 1838 grey_val *= CalcAlpha(fore_col >> 24); \ 1839 if (grey_val > 127) { \ 1840 register U32BIT fa, ba, comp, tmp_c, alpha_c; \ 1842 alpha_c = ((((MAX_ALPHA - ba) *grey_val) + ((MAX_ALPHA *255) / 2)) / (MAX_ALPHA *255)) + ba; \ 1843 fa = (U8BIT)(grey_val / SRC_FORE_MAX); \ 1844 ba = (((MAX_ALPHA - fa) *ba) + (MAX_ALPHA / 2)) / MAX_ALPHA; \ 1845 tmp_c = alpha_c << 24; \ 1846 comp = ba * ((pixel >> 16) & 0xff) + fa * ((fore_col >> 16) & 0xff); \ 1847 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 16; \ 1848 comp = ba * ((pixel >> 8) & 0xff) + fa * ((fore_col >> 8) & 0xff); \ 1849 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 8; \ 1850 comp = ba * (pixel & 0xff) + fa * (fore_col & 0xff); \ 1851 tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c); \ 1858 #undef RenderGlyphFn 1862 #undef IsOpaqueColor 1863 #undef NotTransparent 1864 #undef SignificantFore 1865 #undef CombineAlphaColour 1872 U32BIT m_size, glph_count;
1874 if (unistr.len < MAX_NUM_CHARS)
1883 for (glph_count = 0; glph_count != unistr.len; glph_count++)
1885 switch (unistr.data[glph_count])
1888 if (glph_count + 1 != unistr.len)
1892 if ((unistr.data[glph_count] <= 0x5e) &&
1893 (unistr.data[glph_count] >= 0x40) &&
1894 (glph_count + 1 != unistr.len))
1897 if ((glph_count + unistr.data[glph_count]) <= unistr.len)
1899 glph_count += unistr.data[glph_count];
1908 case UNICODE_HARD_SPACE:
1909 case UNICODE_FIGURE_SPACE:
1911 if ((attrib->justify & JFY_HZ_MASK) == JUSTIFY_H_CENTRE)
1918 if (unistr.data[glph_count] > 0x20)
1925 if (attrib->entry_point != -1)
1929 if (m_size > MAX_NUM_CHARS)
1933 TRACE(TTEXT, (
"malloc char_data array (sz=%d) at 0x%x", m_size, char_data))
1961 U16BIT line_count, glph_count;
1965 TRACE(TTEXT, (
"SD box=(%d,%d,%d,%d)", txt_box.left, txt_box.top, txt_box.left + txt_box.width, txt_box.top + txt_box.height))
1966 TRACE_UNIC(TTEXT, unistr.data, unistr.len)
1968 f_szdata = attrib->font.hdl;
1970 if ((f_szdata != NULL) &&
1971 (txt_box.width > f_szdata->bb_sd_width) &&
1972 (txt_box.height >= f_szdata->bb_sd_height))
1974 U16BIT available_lines;
1977 TRACE(TTEXT, (
"font=%x width=%d, height=%d posn=(%d,%d) ls=%d", attrib->font.hdl->fnt_id,
1978 txt_box.width, txt_box.height, txt_box.left, txt_box.top, attrib->line_space))
1980 draw.left = (S16BIT)((txt_box.left * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div);
1981 draw.top = (S16BIT)((txt_box.top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div);
1982 draw.right = (S16BIT)txt_box.width;
1983 draw.bottom = (S16BIT)txt_box.height;
1984 draw.right = (S16BIT)(((draw.right + txt_box.left) * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div);
1985 draw.bottom = (S16BIT)(((draw.bottom + txt_box.top) * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div);
1988 if (attrib->line_space == 0)
1991 available_lines = MAX_NUM_LINES;
1995 available_lines = (U16BIT)(((txt_box.height - f_szdata->bb_sd_height) / attrib->line_space) + 1);
1996 if (available_lines > MAX_NUM_LINES)
1999 TRACE(TERROR, (
"Num of text lines was restricted from %d to %d", available_lines, MAX_NUM_LINES))
2000 available_lines = MAX_NUM_LINES;
2006 char_data = GetCharArray( unistr, attrib, chars );
2007 if (char_data == NULL)
2013 line_count = PreparePrintableData( unistr, attrib, f_szdata, font_ptr, draw.right - draw.left,
2014 (U16BIT)txt_box.width, available_lines, lines, char_data, &glph_count );
2015 if (line_count > 0 && glph_count > 0)
2018 TRACE(TTEXT, (
"HD box=(%d,%d,%d,%d)", draw.left, draw.top, draw.right, draw.bottom))
2019 TRACE(TTEXT, (
"lines(%d,%d) left=%d avl_width=%d", available_lines, line_count, f_szdata->bound_box.left,
2020 txt_box.width - f_szdata->spxl_xleftoffset))
2021 if (TTEXT & mheg_trace_debug)
2022 trace_lines( line_count, lines, char_data, f_szdata->fnt_id & 0xff, font_ptr->metric_resolution );
2025 canvas = OSD_MemAlloc(
sizeof(
S_SURFACE));
2029 canvas->width = draw.right - draw.left;
2030 canvas->height = draw.bottom - draw.top;
2031 canvas->srf_type = SRF_TYPE_TXT;
2032 TRACE(TTEXT, (
"canvas=(%d,%d)", canvas->width, canvas->height))
2034 if (attrib->line_space == 0)
2036 available_lines = line_count;
2039 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
2042 canvas->col_buff = OSD_MemAlloc( canvas->width * canvas->height );
2043 canvas->hw_handle = NULL;
2044 if (canvas->col_buff != NULL)
2046 canvas->buff_pitch = canvas->width;
2047 memset( canvas->col_buff,
2048 OSD_FindNearestColourIndex(0x00000000),
2049 canvas->width * canvas->height );
2051 TextDraw8Bit( lines, char_data, f_szdata, font_ptr->face,
2052 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2053 attrib->line_space, txt_box.top, txt_box.height,
2054 line_count, available_lines, canvas );
2058 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
2063 OSD_DbgAddSurf( canvas );
2064 if (canvas->hw_handle != NULL)
2066 canvas->buff_pitch = canvas->width << 1;
2068 if (canvas->col_buff)
2070 TextDraw16Bit( lines, char_data, f_szdata, font_ptr->face,
2071 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2072 attrib->line_space, txt_box.top, txt_box.height,
2073 line_count, available_lines, canvas );
2082 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 2085 OSD_DbgAddSurf( canvas );
2086 if (canvas->hw_handle != NULL)
2088 canvas->buff_pitch = canvas->width << 2;
2090 if (canvas->col_buff)
2092 TextDraw32Bit( lines, char_data, f_szdata, font_ptr->face,
2093 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2094 attrib->line_space, txt_box.top, txt_box.height,
2095 line_count, available_lines, canvas );
2104 if (char_data != chars)
2106 OSD_MemFree( char_data );
2110 TRACE(TTEXT, (
"return=0x%x\n", canvas))
2129 U16BIT line_count, glph_count;
2134 TRACE_UNIC(TTEXT, unistr.data, unistr.len)
2136 f_sz = attrib->font.hdl;
2140 TRACE(TERROR, (
"f_sz NULL"))
2141 lines[0].l_width = 0;
2145 TRACE(TTEXT, (
"font id=%x", f_sz->fnt_id))
2149 char_data = GetCharArray( unistr, attrib, chars );
2150 if (char_data != NULL)
2153 attrib->justify = JUSTIFY_H_END;
2154 line_count = PreparePrintableData( unistr, attrib, f_sz,
MG_FindFont(f_sz), mg_ctxt.out_osd_width,
2155 mg_ctxt.out_osd_width, 1, lines, char_data, &glph_count );
2156 if (line_count == 0)
2158 lines[0].l_width = 0;
2160 if (char_data != chars)
2162 OSD_MemFree( char_data );
2167 TRACE(TTEXT, (
"return=%d", lines[0].l_width))
2168 return (S16BIT)lines[0].l_width;
2185 U16BIT line_count, glph_count;
2189 TRACE(TTEXT, (
"box=%d,%d", canvas->width, canvas->height))
2190 TRACE_UNIC(TTEXT, unistr.data, unistr.len)
2192 f_szdata = attrib->font.hdl;
2194 if (f_szdata != NULL && canvas != NULL && canvas->col_buff != NULL &&
2195 (canvas->width > f_szdata->bb_sd_width) &&
2196 (canvas->height >= f_szdata->bb_sd_height))
2198 TRACE(TTEXT, (
"font=%x ls=%d", attrib->font.hdl->fnt_id, attrib->line_space))
2202 char_data = GetCharArray( unistr, attrib, chars );
2203 if (char_data != NULL)
2206 line_count = PreparePrintableData( unistr, attrib, f_szdata, font_ptr, canvas->width,
2207 canvas->width, 1, lines, char_data, &glph_count );
2208 if (line_count > 0 && glph_count > 0)
2211 TRACE(TTEXT, (
"lines(%d,%d)", 1, line_count))
2212 if (TTEXT & mheg_trace_debug)
2213 trace_lines( line_count, lines, char_data, f_szdata->fnt_id & 0xff, font_ptr->metric_resolution );
2218 TRACE(TTEXT, (
"canvas (buf=%p,%d,%d)", canvas->col_buff, canvas->width, canvas->height))
2220 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
2223 TextDraw8Bit( lines, char_data, f_szdata, font_ptr->face,
2224 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2225 attrib->line_space, 0, canvas->height,
2226 line_count, 1, canvas );
2229 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
2232 TextDraw16BitBlend( lines, char_data, f_szdata, font_ptr->face,
2233 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2234 attrib->line_space, 0, canvas->height,
2235 line_count, 1, canvas );
2241 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 2242 TextDraw32BitBlend( lines, char_data, f_szdata, font_ptr->face,
2243 attrib->justify & JUSTIFY_V_JUSTIFIED, attrib->justify & JUSTIFY_H_JUSTIFIED,
2244 attrib->line_space, 0, canvas->height,
2245 line_count, 1, canvas );
2251 if (char_data != chars)
2253 OSD_MemFree( char_data );
2260 if (f_szdata != NULL && canvas != NULL)
2262 TRACE(TTEXT, (
"Size too small: (%d < %d)? or (%d < %d)?", canvas->width, f_szdata->bb_sd_width, canvas->height, f_szdata->bb_sd_height));
2278 if (attrib->font.fp.index == HK_FNT_MAGIC)
2280 return MG_DrawHKText( unistr, attrib, txt_box );
void * MG_DrawUKText(const TextString unistr, pDrawTextAttrib attrib, const VRect txt_box)
Create Surface and draw text string on it and terminate freetype library.
S16BIT MG_TextWidth(const TextString unistr, pDrawTextAttrib attrib)
void MG_DrawScreenText(const TextString unistr, pDrawTextAttrib attrib, S_SURFACE *canvas)
Single line text string drawn on existing Surface.
Font file handling with the Freetype.
void * MG_DrawText(const TextString unistr, pDrawTextAttrib attrib, const VRect txt_box)
Create Surface and draw text string on it and terminate freetype library.
void * STB_OSDMhegCreateSurface(U16BIT width, U16BIT height, BOOLEAN init, U32BIT colour)
Creates a hardware surface on which MHEG5 engine will draw an individual MHEG object. At its basic the function can just allocate the buffer to be returned by STB_OSDMhegLockBuffer(). It's size being: (width * height * bytes_per_pixel) Also, when 'init' is TRUE, function initialises surface buffer to the specified colour. For pixel colour format of less than four bytes, use least significant bits of 'colour'.
void * STB_OSDMhegLockBuffer(void *surface, U32BIT *pPitch)
Converts hardware surface handle returned by STB_OSDMhegCreateSurface() to buffer address that the en...
S_FontDetails * MG_FindFont(H_FontSize f_sz)
Get font from size.
MHEG text render that uses the Freetype font library.
void MG_CheckCache(S_FontSize *f_szdata)
Interface to the MHEG text render that uses Freetype font library.
Interface to the MHEG text render that uses Freetype font library.
Graphics functions required by the HD MHEG5 engine. All references to colour used in these functions ...
void ProcessNewLine(S_PROPERTIES *pp, CharData *chars, S_FontSize *f_sz_data, U16BIT line_num, U8BIT justify)
Process for adding a new line.
void STB_OSDMhegUnlockBuffer(void *surface)
This function informs HW that MHEG5 is finished writing to the buffer.