void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { Std(font); font.Bold(); while(n > 30000) { DrawTextOp(x, y, angle, text, font, ink, 30000, dx); if(dx) for(int i = 0; i < 30000; i++) x += *dx++; else x += GetTextSize(text, font, 30000).cx; n -= 30000; text += 30000; } GuiLock __; COLORREF cr = GetColor(ink); if(cr != lastTextColor) { LLOG("Setting text color: " << ink); ::SetTextColor(handle, lastTextColor = cr); } HGDIOBJ orgfont = ::SelectObject(handle, GetWin32Font(font, angle)); int ascent = font.Info().GetAscent(); if(angle) { double sina, cosa; Draw::SinCos(angle, sina, cosa); Size offset; ::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx); } else ::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text, n, dx); ::SelectObject(handle, orgfont); }
PdfFont* PdfFontCache::GetFont( const wchar_t* pszFontName, bool bBold, bool bItalic, bool bEmbedd, const PdfEncoding * const pEncoding ) { PODOFO_ASSERT( pEncoding ); PdfFont* pFont; std::pair<TISortedFontList,TCISortedFontList> it; it = std::equal_range( m_vecFonts.begin(), m_vecFonts.end(), TFontCacheElement( pszFontName, bBold, bItalic, pEncoding ) ); if( it.first == it.second ) return GetWin32Font( it.first, m_vecFonts, pszFontName, bBold, bItalic, bEmbedd, pEncoding ); else pFont = (*it.first).m_pFont; return pFont; }
String GetFontDataSys(Font font) { String r; HFONT hfont = GetWin32Font(font, 0); if(hfont) { HDC hdc = Win32_IC(); HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); DWORD size = GetFontData(hdc, 0, 0, NULL, 0); if(size == GDI_ERROR) { LLOG("PdfDraw::Finish: GDI_ERROR on font " << pdffont.GetKey(i)); return Null; } StringBuffer b(size); GetFontData(hdc, 0, 0, b, size); ::SelectObject(hdc, ohfont); r = b; } return r; }
PdfFont* PdfFontCache::GetFont( const char* pszFontName, bool bBold, bool bItalic, bool bEmbedd, const PdfEncoding * const pEncoding, const char* pszFileName ) { PODOFO_ASSERT( pEncoding ); PdfFont* pFont; PdfFontMetrics* pMetrics; std::pair<TISortedFontList,TCISortedFontList> it; it = std::equal_range( m_vecFonts.begin(), m_vecFonts.end(), TFontCacheElement( pszFontName, bBold, bItalic, pEncoding ) ); if( it.first == it.second ) { std::string sPath; if ( pszFileName == NULL ) sPath = this->GetFontPath( pszFontName, bBold, bItalic ); else sPath = pszFileName; if( sPath.empty() ) { #ifdef _WIN32 return GetWin32Font( it.first, m_vecFonts, pszFontName, bBold, bItalic, bEmbedd, pEncoding ); #else PdfError::LogMessage( eLogSeverity_Critical, "No path was found for the specified fontname: %s\n", pszFontName ); return NULL; #endif // _WIN32 } pMetrics = new PdfFontMetrics( &m_ftLibrary, sPath.c_str() ); pFont = this->CreateFontObject( it.first, m_vecFonts, pMetrics, bEmbedd, bBold, bItalic, pszFontName, pEncoding ); } else pFont = (*it.first).m_pFont; return pFont; }
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt) { HFONT hfont = GetWin32Font(fnt, 0); if(hfont) { HDC hdc = Win32_IC(); HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); GLYPHMETRICS gm; MAT2 m_matrix; memset(&m_matrix, 0, sizeof(m_matrix)); m_matrix.eM11.value = 1; m_matrix.eM22.value = 1; int gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE, &gm, 0, NULL, &m_matrix); if(gsz < 0) return; StringBuffer gb(gsz); gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE, &gm, gsz, ~gb, &m_matrix); if(gsz < 0) return; RenderCharPath(~gb, gsz, sw, x, y + fnt.GetAscent()); ::SelectObject(hdc, ohfont); } }
CommonFontInfo GetFontInfoSys(Font font) { CommonFontInfo fi; memset(&fi, 0, sizeof(fi)); HFONT hfont = GetWin32Font(font, 0); if(hfont) { HDC hdc = Win32_IC(); HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); fi.ascent = tm.tmAscent; fi.descent = tm.tmDescent; fi.external = tm.tmExternalLeading; fi.internal = tm.tmInternalLeading; fi.height = fi.ascent + fi.descent; fi.lineheight = fi.height + fi.external; fi.overhang = tm.tmOverhang; fi.avewidth = tm.tmAveCharWidth; fi.maxwidth = tm.tmMaxCharWidth; fi.firstchar = tm.tmFirstChar; fi.charcount = tm.tmLastChar - tm.tmFirstChar + 1; fi.default_char = tm.tmDefaultChar; fi.fixedpitch = (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0; fi.ttf = fi.scaleable = tm.tmPitchAndFamily & TMPF_TRUETYPE; if(fi.scaleable) { ABC abc; GetCharABCWidths(hdc, 'o', 'o', &abc); fi.spacebefore = abc.abcA; fi.spaceafter = abc.abcC; } else fi.spacebefore = fi.spaceafter = 0; ::SelectObject(hdc, ohfont); } return fi; }
GlyphInfo GetGlyphInfoSys(Font font, int chr) { static Font fnt[GLYPHINFOCACHE]; static int pg[GLYPHINFOCACHE]; static GlyphInfo li[GLYPHINFOCACHE][256]; ONCELOCK { for(int i = 0; i < GLYPHINFOCACHE; i++) pg[i] = -1; } int page = chr >> 8; int q = CombineHash(font, page) % GLYPHINFOCACHE; if(fnt[q] != font || pg[q] != page) { fnt[q] = font; pg[q] = page; HFONT hfont = GetWin32Font(font, 0); if(!hfont) { GlyphInfo n; memset(&n, 0, sizeof(GlyphInfo)); return n; } HDC hdc = Win32_IC(); HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); int from = page << 8; GlyphInfo *t = li[q]; /* if(page >= 32) { wchar h[3]; h[0] = 'x'; h[1] = 'x'; h[2] = 'x'; int w0 = sGetCW(hdc, h, 2); for(int i = 0; i < 256; i++) { h[1] = from + i; t[i].width = sGetCW(hdc, h, 3) - w0; t[i].lspc = t[i].rspc = 0; } } else */{ bool abca = false, abcw = false; Buffer<ABC> abc(256); abcw = ::GetCharABCWidthsW(hdc, from, from + 256 - 1, abc); #ifndef PLATFORM_WINCE if(!abcw) abca = ::GetCharABCWidthsA(hdc, from, from + 256 - 1, abc); #endif if(abcw) { for(ABC *s = abc, *lim = abc + 256; s < lim; s++, t++) { t->width = s->abcA + s->abcB + s->abcC; t->lspc = s->abcA; t->rspc = s->abcC; } } else { Buffer<int> wb(256); #ifdef PLATFORM_WINCE ::GetCharWidth32(hdc, from, from + 256 - 1, wb); #else ::GetCharWidthW(hdc, from, from + 256 - 1, wb); #endif for(int *s = wb, *lim = wb + 256; s < lim; s++, t++) { t->width = *s - GetFontInfoSys(font).overhang; if(abca) { ABC aa = abc[(byte)ToAscii(from++)]; t->lspc = aa.abcA; t->rspc = aa.abcC; } else t->lspc = t->rspc = 0; } } } #ifndef PLATFORM_WINCE WORD pos[256]; WCHAR wch[256]; for(int i = 0; i < 256; i++) wch[i] = from + i; Win32_GetGlyphIndices(hdc, wch, 256, pos, 1); for(int i = 0; i < 256; i++) if(pos[i] == 0xffff) { li[q][i].width = (int16)0x8000; li[q][i].lspc = li[q][i].rspc = 0; } #endif ::SelectObject(hdc, ohfont); } return li[q][chr & 255]; }