📄 devfont.caching.c
字号:
Raster.size = Raster.rows * Raster.cols; Raster.bitmap = cache->buffer; if (Raster.bitmap == 0) { Raster.bitmap = malloc (Raster.size); memset (Raster.bitmap, 0, Raster.size); /* now render the glyph in the small pixmap */ /* IMPORTANT NOTE: the offset parameters passed to the function */ /* TT_Get_Glyph_Bitmap() must be integer pixel values, i.e., */ /* multiples of 64. HINTING WILL BE RUINED IF THIS ISN'T THE CASE! */ /* This is why we _did_ grid-fit the bounding box, especially xmin */ /* and ymin. */ if (!(pf->fontattr&MWTF_ANTIALIAS)) error = TT_Get_Glyph_Bitmap (pf->glyph, &Raster, -xmin * 64, -ymin * 64); else error = TT_Get_Glyph_Pixmap (pf->glyph, &Raster, -xmin * 64, -ymin * 64); if (error) { free (Raster.bitmap); return; } cache->buffer = Raster.bitmap; }#if MWFREETYPEFONT_CACHEBITMAP if ((memcmp(&gr_foreground,&cache->fg,sizeof(gr_foreground)) != 0) || (memcmp(&gr_background,&cache->bg,sizeof(gr_background)) != 0) || (gr_usebg != cache->usebg)) { if (cache->bitmap) { free(cache->bitmap); cache->bitmap = 0; } } bitmap = cache->bitmap;#else bitmap = 0;#endif if (bitmap == 0) { bitmap = malloc (size * sizeof (MWPIXELVAL)); memset (bitmap, 0, size * sizeof (MWPIXELVAL)); src = (char *) Raster.bitmap; dst = bitmap + (size - width); for (y = ymin; y < ymax; y++) { srcptr = src; dstptr = dst; for (x = xmin; x < xmax; x++) { if (pf->fontattr&MWTF_ANTIALIAS) *dstptr++ = gray_palette[(int) *srcptr]; else { for ( z=0; z <= ((xmax-x-1) < 7 ? (xmax-x-1) : 7); z++ ) *dstptr++ = ((*srcptr << z) & 0x80) ? gr_foreground : gr_background; x += 7; } srcptr++; } src += Raster.cols; dst -= width; }#if MWFREETYPEFONT_CACHEBITMAP cache->fg = gr_foreground; cache->bg = gr_background; cache->usebg = gr_usebg; cache->bitmap = bitmap;#endif } /* Now draw the bitmap ... */ GdArea(psd, x_offset + xmin, y_offset - (ymin + height), width, height, bitmap, MWPF_PIXELVAL);#if !MWFREETYPEFONT_CACHEBITMAP free(bitmap);#endif}/* * Draw unicode 16 text string using FREETYPE type font */static voidfreetype_drawtext(PMWFONT pfont, PSD psd, MWCOORD ax, MWCOORD ay, const void *text, int cc, int flags){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; const unsigned short * str = text; TT_F26Dot6 x = ax, y = ay; TT_Pos vec_x, vec_y; int i; TT_F26Dot6 startx, starty; TT_Outline outline; TT_UShort curchar; TT_Glyph_Metrics metrics; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_F26Dot6 ascent, descent; static unsigned char blend[5] = { 0x00, 0x44, 0x88, 0xcc, 0xff }; static unsigned char virtual_palette[5] = { 0, 1, 2, 3, 4 }; pf->last_glyph_code = -1; /* reset kerning*/ pf->last_pen_pos = -32767; /* * Compute instance ascent & descent values * in fractional units (1/64th pixel) */ TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); ascent = ((properties.horizontal->Ascender * imetrics.y_scale)/0x10000); descent = ((properties.horizontal->Descender*imetrics.y_scale)/0x10000); /* * Offset the starting point if necessary, * FreeType always aligns at baseline */ if (flags&MWTF_BOTTOM) { vec_x = 0; vec_y = descent; TT_Transform_Vector(&vec_x, &vec_y,&pf->matrix); x -= vec_x / 64; y += vec_y / 64; } else if (flags&MWTF_TOP) { vec_x = 0; vec_y = ascent; TT_Transform_Vector(&vec_x, &vec_y,&pf->matrix); x -= vec_x / 64; y += vec_y / 64; } /* Set the "graylevels" */ if (pf->fontattr&MWTF_ANTIALIAS) { TT_Set_Raster_Gray_Palette (engine, virtual_palette); alphablend(psd, gray_palette, gr_foreground, gr_background, blend, 5); } startx = x; starty = y; for (i = 0; i < cc; i++) { curchar = TT_Char_Index (pf->char_map, str[i]); if (TT_Load_Glyph (pf->instance, pf->glyph, curchar, TTLOAD_DEFAULT) != TT_Err_Ok) continue; if (pf->fontrotation) { TT_Get_Glyph_Outline (pf->glyph, &outline); TT_Transform_Outline (&outline, &pf->matrix); } TT_Get_Glyph_Metrics (pf->glyph, &metrics); if ((pf->fontattr&MWTF_KERNING) && pf->can_kern) { if (pf->fontrotation) { vec_x = compute_kernval(pf, curchar); vec_y = 0; TT_Transform_Vector(&vec_x, &vec_y,&pf->matrix); x += vec_x / 64; y -= vec_y / 64; } else x += compute_kernval(pf, curchar) / 64; } drawchar(pf, psd, curchar, x, y); if (pf->fontrotation) { vec_x = metrics.advance; vec_y = 0; TT_Transform_Vector (&vec_x, &vec_y, &pf->matrix); x += vec_x / 64; y -= vec_y / 64; } else { x += metrics.advance / 64; /* Kerning point syndrome avoidance */ if (pf->last_pen_pos > x) x = pf->last_pen_pos; pf->last_pen_pos = x; } pf->last_glyph_code = curchar; } if (pf->fontattr & MWTF_UNDERLINE) GdLine(psd, startx, starty, x, y, FALSE);}/* * Return information about a specified font. */static MWBOOLfreetype_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo){ int i; PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_UShort last_glyph_index; TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); /* Fill up the fields */ pfontinfo->height = (((properties.horizontal->Ascender * \ imetrics.y_scale)/ 0x10000) >> 6) - (((properties.horizontal->Descender * \ imetrics.y_scale)/ 0x10000) >> 6); pfontinfo->maxwidth = ((properties.horizontal->xMax_Extent * \ imetrics.x_scale)/ 0x10000) >> 6; pfontinfo->baseline = ((properties.horizontal->Ascender * \ imetrics.y_scale)/ 0x10000) >> 6; pfontinfo->firstchar = TT_CharMap_First(pf->char_map, NULL); pfontinfo->lastchar = TT_CharMap_Last(pf->char_map, NULL); pfontinfo->fixed = properties.postscript->isFixedPitch; last_glyph_index = properties.num_Glyphs > 255 ? 255: properties.num_Glyphs-1; /* Doesn't work ... don't know why ....*/#if 0 if (TT_Get_Face_Widths( pf->face, 0, last_glyph_index, widths, NULL ) != TT_Err_Ok) { return TRUE; } for(i=0; i<=last_glyph_index; i++) DPRINTF("widths[%d]: %d\n", i, widths[i]);#endif /* Get glyphs widths */ for(i=0; i<=last_glyph_index; i++) pfontinfo->widths[i] = Get_Glyph_Width(pf, i);#if 0 DPRINTF("x_ppem: %d\ny_ppem: %d\nx_scale: %d\ny_scale: %d\n\ x_resolution: %d\ny_resolution: %d\n", imetrics.x_ppem, imetrics.y_ppem, imetrics.x_scale, \ imetrics.y_scale, imetrics.x_resolution, imetrics.y_resolution); DPRINTF("Ascender: %d\nDescender: %d\nxMax_Extent: %d\n\ Mac Style Say Italic?: %d\nMac Style Say Bold?: %d\n\ sTypoAscender: %d\nsTypoDescender: %d\nusWinAscent: %d\n\ usWinDescent: %d\nusFirstCharIndex: %d\nusLastCharIndex: %d\n\ OS2 Say Italic?: %d\nOS2 Say Bold?: %d\nOS2 Say monospaced?: %d\n\ Postscript Say monospaced?: %d\n",\ properties.horizontal->Ascender, properties.horizontal->Descender, properties.horizontal->xMax_Extent, (properties.header->Mac_Style & 0x2)?1:0, (properties.header->Mac_Style & 0x1)?1:0, properties.os2->sTypoAscender, properties.os2->sTypoDescender, properties.os2->usWinAscent, properties.os2->usWinDescent, properties.os2->usFirstCharIndex, properties.os2->usLastCharIndex, (properties.os2->fsSelection & 0x1)?1:0, (properties.os2->fsSelection & 0x20)?1:0, properties.postscript->isFixedPitch, (properties.os2->panose[3] == 9)?1:0);#endif return TRUE;}static voidfreetype_gettextsize(PMWFONT pfont, const void *text, int cc, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; const unsigned short * str = text; TT_F26Dot6 x = 0; int i; TT_UShort curchar; TT_Glyph_Metrics metrics; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); pf->last_glyph_code = -1; /* reset kerning*/ pf->last_pen_pos = -32767; for (i = 0; i < cc; i++) { curchar = TT_Char_Index (pf->char_map, str[i]); if (TT_Load_Glyph (pf->instance, pf->glyph, curchar, TTLOAD_SCALE_GLYPH|TTLOAD_HINT_GLYPH) != TT_Err_Ok) continue; TT_Get_Glyph_Metrics (pf->glyph, &metrics); if ((pf->fontattr&MWTF_KERNING) && pf->can_kern) { x += compute_kernval(pf, curchar) / 64; } x += metrics.advance / 64; /* Kerning point syndrome avoidance */ if (pf->last_pen_pos > x) x = pf->last_pen_pos; pf->last_pen_pos = x; pf->last_glyph_code = curchar; } *pwidth = x; *pheight = (((properties.horizontal->Ascender * imetrics.y_scale)/ 0x10000) >> 6) - (((properties.horizontal->Descender * imetrics.y_scale)/ 0x10000) >> 6); /* FIXME: is it what's required ?? */ *pbase = (((-properties.horizontal->Descender) * imetrics.y_scale)/ 0x10000) >> 6;}static voidfreetype_destroyfont(PMWFONT pfont){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; TT_Close_Face(pf->face); /*----------*/ if (pf->glyph_cache != 0) free_cache_glyph(pf->glyph_cache); /*----------*/ free(pf);}static voidfreetype_setfontsize(PMWFONT pfont, MWCOORD fontsize){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; pf->fontsize = fontsize; /* We want real pixel sizes ... not points ...*/ TT_Set_Instance_PixelSizes( pf->instance, pf->fontsize, pf->fontsize, pf->fontsize * 64 );#if 0 /* set charsize (convert to points for freetype)*/ TT_Set_Instance_CharSize (pf->instance, ((pf->fontsize * 72 + 96/2) / 96) * 64);#endif}static voidfreetype_setfontrotation(PMWFONT pfont, int tenthdegrees){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; float angle; pf->fontrotation = tenthdegrees; /* Build the rotation matrix with the given angle */ TT_Set_Instance_Transform_Flags (pf->instance, TRUE, FALSE); angle = pf->fontrotation * M_PI / 1800; pf->matrix.yy = (TT_Fixed) (cos (angle) * (1 << 16)); pf->matrix.yx = (TT_Fixed) (sin (angle) * (1 << 16)); pf->matrix.xx = pf->matrix.yy; pf->matrix.xy = -pf->matrix.yx;}#endif /* HAVE_FREETYPE_SUPPORT*//* UTF-8 to UTF-16 conversion. Surrogates are handeled properly, e.g. * a single 4-byte UTF-8 character is encoded into a surrogate pair. * On the other hand, if the UTF-8 string contains surrogate values, this * is considered an error and returned as such. * * The destination array must be able to hold as many Unicode-16 characters * as there are ASCII characters in the UTF-8 string. This in case all UTF-8 * characters are ASCII characters. No more will be needed. * * Copyright (c) 2000 Morten Rolland, Screen Media */static intutf8_to_utf16(const unsigned char *utf8, int cc, unsigned short *unicode16){ int count = 0; unsigned char c0, c1; unsigned long scalar; while(--cc >= 0) { c0 = *utf8++; /*DPRINTF("Trying: %02x\n",c0);*/ if ( c0 < 0x80 ) { /* Plain ASCII character, simple translation :-) */ *unicode16++ = c0; count++; continue; } if ( (c0 & 0xc0) == 0x80 ) /* Illegal; starts with 10xxxxxx */ return -1; /* c0 must be 11xxxxxx if we get here => at least 2 bytes */ scalar = c0; if(--cc < 0) return -1; c1 = *utf8++; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x20) ) { /* Two bytes UTF-8 */ if ( scalar < 0x80 ) return -1; /* Overlong encoding */ *unicode16++ = scalar & 0x7ff; count++; continue; } /* c0 must be 111xxxxx if we get here => at least 3 bytes */ if(--cc < 0) return -1; c1 = *utf8++; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x10) ) { /*DPRINTF("####\n");*/ /* Three bytes UTF-8 */ if ( scalar < 0x800 ) return -1; /* Overlong encoding */ if ( scalar >= 0xd800 && scalar < 0xe000 ) return -1; /* UTF-16 high/low halfs */ *unicode16++ = scalar & 0xffff; count++; continue; } /* c0 must be 1111xxxx if we get here => at least 4 bytes */ c1 = *utf8++; if(--cc < 0) return -1; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x08) ) { /* Four bytes UTF-8, needs encoding as surrogates */ if ( scalar < 0x10000 ) return -1; /* Overlong encoding */ scalar -= 0x10000; *unicode16++ = ((scalar >> 10) & 0x3ff) + 0xd800; *unicode16++ = (scalar & 0x3ff) + 0xdc00; count += 2; continue; } return -1; /* No support for more than four byte UTF-8 */ } return count;}#if HAVE_HZK_SUPPORT/* UniCode-16 (MWTF_UC16) to GB(MWTF_ASCII) Chinese Characters conversion. * a single 2-byte UC16 character is encoded into a surrogate pair. * return -1 ,if error; * The destination array must be able to hold as many * as there are Unicode-16 characters. * * Copyright (c) 2000 Tang Hao (TownHall)(tang_hao@263.net). */static intUC16_to_GB(const unsigned char *uc16, int cc, unsigned char *ascii){ FILE* fp; char buffer[256]; unsigned char *uc16p; int i=0,j=0, k; unsigned char *filebuffer; unsigned short *uc16pp,*table; unsigned short uc16px; int length=31504; if (use_big5) length=54840; uc16p=(unsigned char *) uc16; uc16pp=(unsigned short *) uc16; strcpy(buffer,HZK_FONT_DIR); if (use_big5) strcat(buffer,"/BG2UBG.KU"); else strcat(buffer,"/UGB2GB.KU"); if(!(fp = fopen(buffer, "rb"))) { fprintf (stderr, "Error.\nThe %s file can not be found!\n",buffer); return -1; } filebuffer= (unsigned char *)malloc ( length); if(fread(filebuffer, sizeof(char),length, fp) < length) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -