bool Compose(Font font, int chr, ComposedGlyph& cg) { if(chr < 256 || chr > 256 + 128) return false; CGInfo f = gc_info[chr - 256]; if(f.type == CG_NONE) return false; GlyphInfo gi = GetGlyphInfo(font, f.ascii); if(!gi.IsNormal()) return false; int cw = gi.width; CommonFontInfo fi = GetFontInfo(font); gi = GetGlyphInfo(font, f.mark); if(!gi.IsNormal()) return false; int mw = gi.width; cg.mark_font = font; cg.mark_pos.x = cg.mark_pos.y = 0; cg.basic_char = f.ascii; cg.mark_char = f.mark; if(cg.mark_char == CG_COMMA_UR && fi.fixedpitch) cg.mark_char = CG_CARON; if(cg.mark_char == CG_COMMA_T) { cg.mark_pos.y -= 3 * font.GetHeight() / 4; cg.mark_pos.x += 4 * cw / 10; if(font.IsItalic()) cg.mark_pos.x += mw / 2; } else if(cg.mark_char == CG_COMMA_UR) { cg.mark_pos.y -= 2 * font.GetHeight() / 3; cg.mark_pos.x += cw - mw / 4; cg.mark_char = ','; if(font.IsItalic()) cg.mark_pos.x += mw / 3; } else if(cg.mark_char == CG_COMMA_URI) { cg.mark_pos.y -= 2 * font.GetHeight() / 3; cg.mark_pos.x += cw - mw / 2; cg.mark_char = ','; if(font.IsItalic()) cg.mark_pos.x += mw / 3; } else if(cg.mark_char != CG_STROKE) { if(cg.mark_char != CG_OGONEK && cg.mark_char != CG_CEDILLA && f.type == CG_CAPITAL) { cg.mark_font = font(9 * font.GetHeight() / 10); mw = GetGlyphInfo(cg.mark_font, f.mark).width; cg.mark_pos.y -= cg.mark_char == CG_RING_ABOVE ? font.GetHeight() / 19 : font.GetHeight() / 10; } cg.mark_pos.x += (cw - mw) / 2; if(font.IsItalic()) cg.mark_pos.x += mw / 5; } return true; }
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { GuiLock __; int ascent = font.GetAscent(); double sina = 0; double cosa = 1; if(angle) Draw::SinCos(angle, sina, cosa); int xpos = 0; Buffer<cairo_glyph_t> gs(n); for(int i = 0; i < n; i++) { cairo_glyph_t& g = gs[i]; g.index = GetGlyphInfo(font, text[i]).glyphi; g.x = fround(x + cosa * xpos + sina * ascent); g.y = fround(y + cosa * ascent - sina * xpos); xpos += dx ? dx[i] : font[text[i]]; } static LRUCache<FontSysData, Tuple2<Font, int> > cache; FontDataSysMaker m; m.font = font; m.angle = angle; FontSysData& sf = cache.Get(m); cairo_set_scaled_font(cr, sf.scaled_font); SetColor(ink); cairo_show_glyphs(cr, gs, n); cache.Shrink(64); }
NS_IMETHODIMP nsULE::GetPresentationForm(const PRUnichar *aString, PRUint32 aLength, const char *aFontCharset, char *aGlyphs, PRSize *aOutLength, PRBool aIsWide) { PangoliteGlyphString *tmpGlyphs=pangolite_glyph_string_new(); GetGlyphInfo(aString, aLength, tmpGlyphs, aFontCharset); if (tmpGlyphs->num_glyphs > 0) { gint i=0, glyphCt=0; for (i=0; i < tmpGlyphs->num_glyphs; i++, glyphCt++) { if (aIsWide) aGlyphs[glyphCt++]=(unsigned char) ((tmpGlyphs->glyphs[i].glyph & 0xFF00) >> 8); aGlyphs[glyphCt]=(unsigned char)(tmpGlyphs->glyphs[i].glyph & 0x00FF); } *aOutLength = (PRSize)glyphCt; }
void PaintCharacter(Painter& sw, const Pointf& p, int chr, Font font) { GlyphInfo gi = GetGlyphInfo(font, chr); PaintCharPath pw; pw.sw = &sw; if(gi.IsNormal()) font.Render(pw, p.x, p.y, chr); else if(gi.IsReplaced()) { Font fnt = font; fnt.Face(gi.lspc); fnt.Height(gi.rspc); fnt.Render(pw, p.x, p.y + font.GetAscent() - fnt.GetAscent(), chr); } else if(gi.IsComposed()) { ComposedGlyph cg; Compose(font, chr, cg); font.Render(pw, p.x, p.y, cg.basic_char); sw.Div(); cg.mark_font.Render(pw, p.x + cg.mark_pos.x, p.y + cg.mark_pos.y, cg.mark_char); } sw.EvenOdd(true); }
void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { #if defined(flagWINGL) || defined(flagLINUXGL) if(IsNull(ink)) return; DrawTextOp(x, y, angle, text, font, ink, n, dx); #else if(IsNull(ink)) return; if(n < 0) n = wstrlen(text); Std(font); double sina = 0; double cosa = 1; int posx = 0; if(angle) Draw::SinCos(angle, sina, cosa); Font font0 = font; if(GetInfo() & DRAWTEXTLINES) font.Underline(false).Strikeout(false); for(int i = 0; i < n; i++) { wchar chr = text[i]; GlyphInfo gi = GetGlyphInfo(font, chr); if(gi.IsNormal()) if(angle) DrawTextOp(int(x + cosa * posx), int(y - sina * posx), angle, &chr, font, ink, 1, NULL); else { int c = 1; int dd = 0; while(i + c < n && c < 1000) { GlyphInfo gi2 = GetGlyphInfo(font, text[i + c]); if(!gi2.IsNormal()) break; dd += dx ? dx[c - 1] : gi.width; c++; gi = gi2; } DrawTextOp(x + posx, y, 0, text + i, font, ink, c, dx); posx += dd; i += c - 1; if(dx) dx += c - 1; } else if(gi.IsReplaced()) { Font fnt = font; fnt.Face(gi.lspc); fnt.Height(gi.rspc); if(angle) DrawTextOp(int(x + cosa * posx), int(y - sina * (font.GetAscent() - fnt.GetAscent() + posx)), angle, &chr, fnt, ink, 1, NULL); else DrawTextOp(x + posx, y + font.GetAscent() - fnt.GetAscent(), 0, &chr, fnt, ink, 1, NULL); GlyphMetrics(gi, font, chr); } else if(gi.IsComposed()) { ComposedGlyph cg; Compose(font, chr, cg); if(angle) { DrawTextOp(int(x + cosa * posx), int(y - sina * posx), angle, &cg.basic_char, font, ink, 1, NULL); DrawTextOp(int(x + cosa * (posx + cg.mark_pos.x)), int(y - sina * (cg.mark_pos.y + posx)), angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); } else { DrawTextOp(x + posx, y, 0, &cg.basic_char, font, ink, 1, NULL); DrawTextOp(x + cg.mark_pos.x + posx, y + cg.mark_pos.y, 0, &cg.mark_char, cg.mark_font, ink, 1, NULL); } GlyphMetrics(gi, font, chr); } else { Font fnt = Arial(font.GetHeight()); wchar chr = 0x25a1; gi = GetGlyphInfo(fnt, chr); if(!gi.IsNormal()) { chr = ' '; gi = GetGlyphInfo(fnt, chr); } if(angle) DrawTextOp(int(x + cosa * posx), int(y - sina * posx), angle, &chr, fnt, ink, 1, NULL); else DrawTextOp(x + posx, y, 0, &chr, fnt, ink, 1, NULL); } posx += dx ? *dx++ : gi.width; } if((GetInfo() & DRAWTEXTLINES) && (font0.IsUnderline() || font0.IsStrikeout())) { int hg = abs(font0.GetCy()); if(hg == 0) hg = 10; int thickness = max(hg / 20, 1); int ascent = font0.GetAscent(); Size offset = Point(0, ascent); if(angle) { offset.cx = fround(ascent * sina); offset.cy = fround(ascent * cosa); } x += offset.cx; y += offset.cy; if(font0.IsUnderline()) { int p = max(hg / 15, int(font0.Info().GetDescent() > 0)); DrawLine( int(x + p * sina), int(y + p * cosa), int(x + posx * cosa + p * sina), int(y - posx * sina + p * cosa), thickness, ink ); } if(font0.IsStrikeout()) { int p = -ascent / 3; DrawLine( int(x + p * sina), int(y + p * cosa), int(x + posx * cosa + p * sina), int(y - posx * sina + p * cosa), thickness, ink ); } } #endif }
void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { #ifdef flagWINGL if(IsNull(ink)) return; DrawTextOp(x, y, angle, text, font, ink, n, dx); #else if(IsNull(ink)) return; if(n < 0) n = wstrlen(text); Std(font); double sina; double cosa; int d = 0; if(angle) Draw::SinCos(angle, sina, cosa); for(int i = 0; i < n; i++) { wchar chr = text[i]; GlyphInfo gi = GetGlyphInfo(font, chr); if(gi.IsNormal()) if(angle) DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &chr, font, ink, 1, NULL); else { int c = 1; int dd = 0; while(i + c < n) { GlyphInfo gi2 = GetGlyphInfo(font, text[i + c]); if(!gi2.IsNormal()) break; dd += dx ? dx[c] : gi.width; c++; gi = gi2; } DrawTextOp(x + d, y, 0, text + i, font, ink, c, dx); d += dd; i += c - 1; if(dx) dx += c - 1; } else if(gi.IsReplaced()) { Font fnt = font; fnt.Face(gi.lspc); fnt.Height(gi.rspc); if(angle) DrawTextOp(int(x + cosa * d), int(y - sina * (font.GetAscent() - fnt.GetAscent() + d)), angle, &chr, fnt, ink, 1, NULL); else DrawTextOp(x + d, y + font.GetAscent() - fnt.GetAscent(), 0, &chr, fnt, ink, 1, NULL); GlyphMetrics(gi, font, chr); } else if(gi.IsComposed()) { ComposedGlyph cg; Compose(font, chr, cg); if(angle) { DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &cg.basic_char, font, ink, 1, NULL); DrawTextOp(int(x + cosa * (d + cg.mark_pos.x)), int(y - sina * (cg.mark_pos.y + d)), angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); } else { DrawTextOp(x + d, y, 0, &cg.basic_char, font, ink, 1, NULL); DrawTextOp(x + cg.mark_pos.x + d, y + cg.mark_pos.y, 0, &cg.mark_char, cg.mark_font, ink, 1, NULL); } GlyphMetrics(gi, font, chr); } else { Font fnt = Arial(font.GetHeight()); wchar chr = 0x25a1; gi = GetGlyphInfo(fnt, chr); if(!gi.IsNormal()) { chr = ' '; gi = GetGlyphInfo(fnt, chr); } if(angle) DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &chr, fnt, ink, 1, NULL); else DrawTextOp(x + d, y, 0, &chr, fnt, ink, 1, NULL); } d += dx ? *dx++ : gi.width; } #endif }