diff --git a/uppsrc/CtrlCore/CtrlCoreInit.cpp b/uppsrc/CtrlCore/CtrlCoreInit.cpp index f88dc17fd..18ee8438c 100644 --- a/uppsrc/CtrlCore/CtrlCoreInit.cpp +++ b/uppsrc/CtrlCore/CtrlCoreInit.cpp @@ -5,15 +5,15 @@ namespace Upp { #define TFILE #include -static Image sRenderGlyph(int cx, int x, Font font, int chr, int py, int pcy) +static Image sRenderGlyph(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg) { ImageDraw iw(cx, pcy); - iw.DrawRect(0, 0, cx, pcy, White); - iw.DrawText(x, -py, WString(chr, 1), font, Black); + iw.DrawRect(0, 0, cx, pcy, bg); + iw.DrawText(x, -py, WString(chr, 1), font, fg); return iw; } -void SetRenderGlyph(Image (*f)(int cx, int x, Font font, int chr, int py, int pcy)); +void SetRenderGlyph(Image (*f)(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg)); INITIALIZER(CtrlCore) { SetRenderGlyph(sRenderGlyph); diff --git a/uppsrc/Draw/Draw.h b/uppsrc/Draw/Draw.h index bd8ed7789..9db404fef 100644 --- a/uppsrc/Draw/Draw.h +++ b/uppsrc/Draw/Draw.h @@ -103,11 +103,11 @@ public: SANSSERIF, MONOSPACE, #ifdef PLATFORM_WIN32 - SYMBOL, - WINGDINGS, - TAHOMA, + SYMBOL, // deprecated + WINGDINGS, // deprecated + TAHOMA, // deprecated #endif - OTHER, + OTHER, // deprecated // Backward compatibility: ROMAN = SERIF, @@ -978,8 +978,13 @@ IsJPGFnType GetIsJPGFn(); #include "DDARasterizer.h" #include "SDraw.h" -bool ReadCmap(const char *ptr, int count, Event range, bool glyphs); -bool ReadCmap(Font font, Event range, bool glyphs = false); +enum { + CMAP_GLYPHS = 1, + CMAP_ALLOW_SYMBOL = 2, +}; + +bool ReadCmap(const char *ptr, int count, Event range, dword flags = 0); +bool ReadCmap(Font font, Event range, dword flags = 0); bool GetPanoseNumber(Font font, byte *panose); } diff --git a/uppsrc/Draw/DrawUtil.cpp b/uppsrc/Draw/DrawUtil.cpp index b440d7457..524b7f1ee 100644 --- a/uppsrc/Draw/DrawUtil.cpp +++ b/uppsrc/Draw/DrawUtil.cpp @@ -611,22 +611,22 @@ IsJPGFnType GetIsJPGFn() return sIsJPG; } -Image (*render_glyph)(int cx, int x, Font font, int chr, int py, int pcy); +Image (*render_glyph)(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg); -Image RenderGlyph(int cx, int x, Font font, int chr, int py, int pcy) +Image RenderGlyph(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg) { if(render_glyph) - return (*render_glyph)(cx, x, font, chr, py, pcy); + return (*render_glyph)(cx, x, font, chr, py, pcy, fg, bg); if(ImageAnyDraw::IsAvailable()) { ImageAnyDraw iw(cx, pcy); - iw.DrawRect(0, 0, cx, pcy, White); - iw.DrawText(x, -py, WString(chr, 1), font, Black); + iw.DrawRect(0, 0, cx, pcy, bg); + iw.DrawText(x, -py, WString(chr, 1), font, fg); return iw; } return Null; } -void SetRenderGlyph(Image (*f)(int cx, int x, Font font, int chr, int py, int pcy)) +void SetRenderGlyph(Image (*f)(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg)) { render_glyph = f; } diff --git a/uppsrc/Draw/FontCR.cpp b/uppsrc/Draw/FontCR.cpp index e139be401..d3e009214 100644 --- a/uppsrc/Draw/FontCR.cpp +++ b/uppsrc/Draw/FontCR.cpp @@ -234,11 +234,12 @@ struct sRFace { #include "Fonts.i" }; -bool ReadCmap(const char *ptr, int count, Event range, bool glyphs) +bool ReadCmap(const char *ptr, int count, Event range, dword flags) { + auto Get8 = [&](int i) { return i >= 0 && i + 1 <= count ? (byte)ptr[i] : 0; }; auto Get16 = [&](int i) { return i >= 0 && i + 2 <= count ? Peek16be(ptr + i) : 0; }; auto Get32 = [&](int i) { return i >= 0 && i + 4 <= count ? Peek32be(ptr + i) : 0; }; - for(int pass = 0; pass < 2; pass++) { + for(int pass = 0; pass < (flags & CMAP_ALLOW_SYMBOL ? 3 : 2); pass++) { int p = 0; p += 2; int n = Get16(p); @@ -263,7 +264,6 @@ bool ReadCmap(const char *ptr, int count, Event range, bool glyph } return true; } - else if(((pid == 3 && psid == 1) || (pid == 0 && psid == 3) && format == 4) && pass == 1) { int p = offset; int n = Get16(p + 6) >> 1; @@ -276,7 +276,7 @@ bool ReadCmap(const char *ptr, int count, Event range, bool glyph int end = Get16(seg_end + 2 * i); int delta = Get16(idDelta + 2 * i); int ro = Get16(idRangeOffset + 2 * i); - if(glyphs) { + if(flags & CMAP_GLYPHS) { if (ro && delta == 0) { LLOG("RangeOffset start: " << start << ", end: " << end << ", delta: " << (int16)delta); int q = idRangeOffset + 2 * i + ro; @@ -295,15 +295,21 @@ bool ReadCmap(const char *ptr, int count, Event range, bool glyph } return true; } + if(pid == 1 && psid == 0 && Get16(offset) == 0 && pass == 2) { + LLOG("Reading symbol cmap"); + for(int i = 0; i < 256; i++) + range(i, i, Get8(offset + 6 + i)); + return true; + } } } return false; } -bool ReadCmap(Font font, Event range, bool glyphs) +bool ReadCmap(Font font, Event range, dword flags) { String h = font.GetData("cmap"); - return ReadCmap(h, h.GetCount(), range, glyphs); + return ReadCmap(h, h.GetCount(), range, flags); } bool GetPanoseNumber(Font font, byte *panose) diff --git a/uppsrc/PdfDraw/PdfDraw.cpp b/uppsrc/PdfDraw/PdfDraw.cpp index fe4cad37e..0d45d379d 100644 --- a/uppsrc/PdfDraw/PdfDraw.cpp +++ b/uppsrc/PdfDraw/PdfDraw.cpp @@ -1,4 +1,5 @@ #include "PdfDraw.h" +#include "CtrlLib/CtrlLib.h" namespace Upp { @@ -294,11 +295,11 @@ PdfDraw::OutlineInfo PdfDraw::GetOutlineInfo(Font fnt) if(q >= 0) return outline_info[q]; OutlineInfo of; - of.sitalic = of.ttf = false; + of.sitalic = of.standard_ttf = false; TTFReader ttf; if(ttf.Open(fnt, false, true)) { - of.ttf = true; + of.standard_ttf = true; of.sitalic = fnt.IsItalic() && (ttf.head.macStyle & 2) == 0; of.sbold = fnt.IsBold() && (ttf.head.macStyle & 1) == 0; LLOG(fnt << ", sbold: " << of.sbold << ", sitalic: " << of.sitalic); @@ -324,7 +325,7 @@ void PdfDraw::DrawTextOp(int x, int y, int angle, const wchar *s, Font fnt, Font ff = fnt; int fh = fnt.GetHeight(); OutlineInfo of = GetOutlineInfo(fnt); - if(of.ttf) + if(of.standard_ttf) fnt.Height(FONTHEIGHT_TTF); String txt; PutrgColor(ink); @@ -385,7 +386,7 @@ void PdfDraw::Escape(const String& data) this->data = data.Mid(5); } -Image RenderGlyph(int cx, int x, Font font, int chr, int py, int pcy); +Image RenderGlyph(int cx, int x, Font font, int chr, int py, int pcy, Color fg, Color bg); PdfDraw::RGlyph PdfDraw::RasterGlyph(Font fnt, int chr) { @@ -409,7 +410,7 @@ PdfDraw::RGlyph PdfDraw::RasterGlyph(Font fnt, int chr) int y = 0; while(y < rg.sz.cy) { int ccy = min(16, rg.sz.cy - y); - Image m = RenderGlyph(rg.sz.cx, rg.x, fnt, chr, y, ccy); + Image m = RenderGlyph(rg.sz.cx, rg.x, fnt, chr, y, ccy, Black(), White()); for(int i = 0; i < m.GetHeight(); i++) { fmt.Write(ob, m[i], rg.sz.cx, NULL); rg.data.Cat((const char *)~ob, linebytes); @@ -865,8 +866,8 @@ String PdfDraw::Finish(const PdfSignatureInfo *sign) << " " << -1000 * fi.GetDescent() / fa << " cm BI /W " << rg.sz.cx << " /H " << rg.sz.cy - << " /BPC 1 /IM true /D [0 1] ID\n" - << rg.data + << " /BPC 1 /IM true /D [0 1]" + << " ID\n" << rg.data << "\nEI Q" ; PutStream(proc); diff --git a/uppsrc/PdfDraw/PdfDraw.h b/uppsrc/PdfDraw/PdfDraw.h index 29096f328..fa411b450 100644 --- a/uppsrc/PdfDraw/PdfDraw.h +++ b/uppsrc/PdfDraw/PdfDraw.h @@ -217,7 +217,7 @@ public: String ps_name; int GetGlyph(wchar chr) { return glyph_map.Get(chr, 0); } - word GetAdvanceWidth(wchar chr) { return glyphinfo[GetGlyph(chr)].advanceWidth; } + word GetAdvanceWidth(wchar chr) { int i = glyph_map.Get(chr, 0); return i < glyphinfo.GetCount() ? glyphinfo[GetGlyph(chr)].advanceWidth : 0; } String Subset(const Vector& chars, int first = 0, bool os2 = false); bool Open(const Font& fnt, bool symbol = false, bool justcheck = false); @@ -278,7 +278,7 @@ private: struct CharPos : Moveable { word fi, ci; }; struct OutlineInfo : Moveable { - bool ttf; + bool standard_ttf; bool sitalic; bool sbold; }; diff --git a/uppsrc/PdfDraw/TTFReader.cpp b/uppsrc/PdfDraw/TTFReader.cpp index 923a7848e..1310f773e 100644 --- a/uppsrc/PdfDraw/TTFReader.cpp +++ b/uppsrc/PdfDraw/TTFReader.cpp @@ -138,9 +138,6 @@ bool TTFReader::Open(const Font& fnt, bool symbol, bool justcheck) LDUMP(post.underlineThickness); LDUMP(post.italicAngle); - if(justcheck) - return true; - Seek("hhea", is); hhea.Serialize(is); LDUMP(hhea.ascent); @@ -154,7 +151,11 @@ bool TTFReader::Open(const Font& fnt, bool symbol, bool justcheck) glyphinfo.SetCount(maxp.numGlyphs); + if(justcheck) + return ReadCmap(fnt, [&](int, int, int) {}, CMAP_ALLOW_SYMBOL); + const char *s = Seek("hmtx"); + if(!s) Error(); int aw = 0; for(i = 0; i < hhea.numOfLongHorMetrics; i++) { aw = glyphinfo[i].advanceWidth = (uint16)Read16(s); @@ -166,6 +167,7 @@ bool TTFReader::Open(const Font& fnt, bool symbol, bool justcheck) } s = Seek("loca"); + if(!s) Error(); for(i = 0; i < maxp.numGlyphs; i++) if(head.indexToLocFormat) { glyphinfo[i].offset = Peek32(s, i); @@ -180,67 +182,13 @@ bool TTFReader::Open(const Font& fnt, bool symbol, bool justcheck) LLOG(i << " advance: " << glyphinfo[i].advanceWidth << ", left: " << glyphinfo[i].leftSideBearing << ", offset: " << glyphinfo[i].offset << ", size: " << glyphinfo[i].size); - int len; - const char *cmap = Seek("cmap", len); - ReadCmap(cmap, len, [&](int start, int end, int glyph) { + ReadCmap(fnt, [&](int start, int end, int glyph) { for(int ch = start; ch <= end; ch++) SetGlyph(ch, glyph++); - }, true); - - #if 0 - s = Seek("cmap"); - const char *p = s; - p += 2; - n = Read16(p); - while(n--) { - int pid = Read16(p); - int psid = Read16(p); - int offset = Read32(p); - LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << Peek16(s + offset)); - //Test with Symbol font !!!; improve - Unicode first, 256 bytes later..., symbol... - if(symbol) { - if(pid == 1 && psid == 0 && Peek16(s + offset) == 0) { - LLOG("Reading symbol table"); - p = s + offset + 6; - for(int i = 0; i < 256; i++) - SetGlyph(i, (byte)p[i]); - break; - } - } - else - if(pid == 3 && psid == 1) { - p = s + offset; - n = Peek16(p + 6) >> 1; - LLOG("Found UNICODE encoding, offset " << offset << ", segments " << n); - const char *seg_end = p + 14; - const char *seg_start = seg_end + 2 * n + 2; - const char *idDelta = seg_start + 2 * n; - const char *idRangeOffset = idDelta + 2 * n; - for(int i = 0; i < n; i++) { - int start = Peek16(seg_start, i); - int end = Peek16(seg_end, i); - int delta = Peek16(idDelta, i); - int ro = Peek16(idRangeOffset, i); - if (ro && delta == 0) { - LLOG("RangeOffset start: " << start << ", end: " << end << ", delta: " << (int16)delta); - LLOG("ro " << ro); - const char *q = idRangeOffset + 2 * i + ro; - for(int c = start; c <= end; c++) { - SetGlyph(c, (word)Read16(q)); - } - } - else { - LLOG("start: " << start << ", end: " << end << ", delta: " << (int16)delta); - for(int c = start; c <= end; c++) - SetGlyph(c, c + delta); - } - } - break; - } - } - #endif + }, CMAP_GLYPHS|CMAP_ALLOW_SYMBOL); const char *strings = Seek("name"); + if(!strings) Error(); s = strings + 2; int count = Read16(s); strings += (word)Read16(s); diff --git a/upptst/PdfText2/PdfText.cpp b/upptst/PdfText2/PdfText.cpp index 2f89c5d69..0deccc5a7 100644 --- a/upptst/PdfText2/PdfText.cpp +++ b/upptst/PdfText2/PdfText.cpp @@ -1,3 +1,4 @@ +#include #include using namespace Upp; @@ -10,15 +11,14 @@ CONSOLE_APP_MAIN Font fnt(face, 100); Cout() << fnt << "\n"; LOG(face << ' ' << fnt << ", TTF: " << fnt.IsTrueType()); - if(1 || fnt.IsTrueType()) { - pdf.DrawText(0, cy, AsString(fnt), fnt, Black); - pdf.DrawText(200, cy, AsString(fnt), StdFont(100), Black); - cy += fnt.GetLineHeight(); - if(cy > 6000) { - pdf.EndPage(); - pdf.StartPage(); - cy = 0; - } + String txt = AsString(fnt) + " 訓民正音 (훈민정음) 😜 🤪 "; + pdf.DrawText(0, cy, txt, fnt, Black); + pdf.DrawText(3000, cy, AsString(fnt), StdFont(100), Black); + cy += fnt.GetLineHeight(); + if(cy > 6000) { + pdf.EndPage(); + pdf.StartPage(); + cy = 0; } } String p = GetHomeDirFile("pdf.pdf"); diff --git a/upptst/PdfText2/PdfText2.upp b/upptst/PdfText2/PdfText2.upp index b22df9307..56ef50382 100644 --- a/upptst/PdfText2/PdfText2.upp +++ b/upptst/PdfText2/PdfText2.upp @@ -1,10 +1,11 @@ uses Core, - PdfDraw; + PdfDraw, + CtrlLib; file PdfText.cpp; mainconfig - "" = ""; + "" = "GUI";