PdfDraw: Improvements

This commit is contained in:
Mirek Fidler 2022-01-05 08:45:00 +01:00
parent 4f32c54c69
commit f2ce3bfc75
9 changed files with 63 additions and 102 deletions

View file

@ -5,15 +5,15 @@ namespace Upp {
#define TFILE <CtrlCore/CtrlCore.t>
#include <Core/t.h>
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);

View file

@ -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<int, int, int> range, bool glyphs);
bool ReadCmap(Font font, Event<int, int, int> range, bool glyphs = false);
enum {
CMAP_GLYPHS = 1,
CMAP_ALLOW_SYMBOL = 2,
};
bool ReadCmap(const char *ptr, int count, Event<int, int, int> range, dword flags = 0);
bool ReadCmap(Font font, Event<int, int, int> range, dword flags = 0);
bool GetPanoseNumber(Font font, byte *panose);
}

View file

@ -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;
}

View file

@ -234,11 +234,12 @@ struct sRFace {
#include "Fonts.i"
};
bool ReadCmap(const char *ptr, int count, Event<int, int, int> range, bool glyphs)
bool ReadCmap(const char *ptr, int count, Event<int, int, int> 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<int, int, int> 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<int, int, int> 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<int, int, int> 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<int, int, int> range, bool glyphs)
bool ReadCmap(Font font, Event<int, int, int> 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)

View file

@ -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);

View file

@ -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<wchar>& 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<CharPos> { word fi, ci; };
struct OutlineInfo : Moveable<OutlineInfo> {
bool ttf;
bool standard_ttf;
bool sitalic;
bool sbold;
};

View file

@ -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);

View file

@ -1,3 +1,4 @@
#include <CtrlLib/CtrlLib.h>
#include <PdfDraw/PdfDraw.h>
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");

View file

@ -1,10 +1,11 @@
uses
Core,
PdfDraw;
PdfDraw,
CtrlLib;
file
PdfText.cpp;
mainconfig
"" = "";
"" = "GUI";