From 6a71cc487f70da5831c9267ab824881868bae43d Mon Sep 17 00:00:00 2001 From: ketmar Date: Wed, 27 Jul 2016 03:40:56 +0000 Subject: [PATCH] better text styles FossilOrigin-Name: a2c40aa220327084d73e5f41861bcd0a9bd1c9b2283dff64f2af70c37d031069 --- xiniz.d | 14 ++++++++++++++ xlayouter.d | 23 +++++++++++++++++++---- xreader.d | 53 ++++++++++++++++++++++------------------------------- xreadercfg.d | 39 +++++++++++---------------------------- xreaderfmt.d | 27 ++++++++++++++++++--------- 5 files changed, 84 insertions(+), 72 deletions(-) diff --git a/xiniz.d b/xiniz.d index 8d1de77..6f759e3 100644 --- a/xiniz.d +++ b/xiniz.d @@ -16,10 +16,13 @@ */ module xiniz /*is aliced*/; +import iv.nanovg; import iv.strex; import iv.vfs; +import iv.vfs.io; +// ////////////////////////////////////////////////////////////////////////// // void xiniParse(A...) (VFile fl, A args) { import std.traits; char[] line, linebuf; @@ -72,6 +75,17 @@ void xiniParse(A...) (VFile fl, A args) { } else { *(args[idx+1]) = to!T(value); } + } else static if (is(T == NVGColor)) { + uint v; + if (value.length > 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { + v = to!uint(value[2..$], 16); + if (value.length <= 2+3*2) v |= 0xff000000; + } else { + v = to!uint(value); + v |= 0xff000000; + } + *(args[idx+1]) = NVGColor.fromHtml(v); + //writefln("v=0x%08x; r=%s; g=%s; b=%s; a=%s", v, (*(args[idx+1])).r, (*(args[idx+1])).g, (*(args[idx+1])).b, (*(args[idx+1])).a); } else { *(args[idx+1]) = to!T(value); } diff --git a/xlayouter.d b/xlayouter.d index 7889a37..6484891 100644 --- a/xlayouter.d +++ b/xlayouter.d @@ -48,6 +48,7 @@ public: // list of known font faces, should be filled by caller when this object created // DO NOT MODIFY! int[string] fontfaces; + string[int] fontfaceids; private: bool killFontStash; @@ -88,15 +89,27 @@ public: if (name in fontfaces) throw new Exception("duplicate font '"~name.idup~"'"); int fid = fs.fonsAddFont(name, path); if (fid < 0) throw new Exception("font '"~name~"' is not found at '"~path.idup~"'"); - static if (is(T == string)) fontfaces[name] = fid; else fontfaces[name.idup] = fid; + static if (is(T == string)) { + fontfaces[name] = fid; + fontfaceids[fid] = name; + } else { + string n = name.idup; + fontfaces[n] = fid; + fontfaceids[fid] = n; + } } } - @property int fontFace (const(char)[] name) { + @property int fontFaceId (const(char)[] name) { if (auto fid = name in fontfaces) return *fid; return -1; } + @property string fontFace (int fid) { + if (auto ff = fid in fontfaceids) return *ff; + return null; + } + void setFont() (in auto ref LayFontStyle style) { int fsz = style.fontsize; if (fsz < 1) fsz = 1; @@ -557,14 +570,16 @@ public: @property ref LayFontStyle fontStyle () pure nothrow @safe @nogc { pragma(inline, true); return newStyle; } @property ref LayLineStyle lineStyle () pure nothrow @safe @nogc { pragma(inline, true); return newJust; } - @property int fontFace (const(char)[] name) { + @property int fontFaceId (const(char)[] name) { if (laf !is null) { - int fid = laf.fontFace(name); + int fid = laf.fontFaceId(name); if (fid >= 0) return fid; } throw new Exception("unknown font face '"~name.idup~"'"); } + @property string fontFace (int fid) { pragma(inline, true); return (laf !is null ? laf.fontFace(fid) : null); } + void endLine () { put(EndLineCh); } void endPara () { put(EndParaCh); } diff --git a/xreader.d b/xreader.d index 9dc19e6..05c5190 100644 --- a/xreader.d +++ b/xreader.d @@ -669,12 +669,7 @@ void run (string bookFileName) { //glClearColor(0, 0, 0, 0); //glClearColor(0.18, 0.18, 0.18, 0); - glClearColor( - cast(float)((colorBack>>16)&0xff)/255.0f, - cast(float)((colorBack>>8)&0xff)/255.0f, - cast(float)(colorBack&0xff)/255.0f, - 0 - ); + glClearColor(colorBack.r, colorBack.g, colorBack.b, 0); glClear(glNVGClearFlags|EliteModel.glClearFlags); refreshed(); @@ -697,7 +692,7 @@ void run (string bookFileName) { if (laytext is null) { if (shipModel is null) { vg.beginPath(); - vg.fillColor(u2c(colorText)); + vg.fillColor(colorText); int drawY = (GHeight-textHeight)/2; vg.intersectScissor((sbLeft ? 2+BND_SCROLLBAR_WIDTH+2 : 4), drawY, GWidth-4-2-BND_SCROLLBAR_WIDTH-2, textHeight); vg.fontFaceId(textFont); @@ -710,7 +705,7 @@ void run (string bookFileName) { // draw text page if (laytext !is null && laytext.lineCount) { vg.beginPath(); - vg.fillColor(u2c(colorText)); + vg.fillColor(colorText); int drawY = (GHeight-textHeight)/2; vg.intersectScissor((sbLeft ? 2+BND_SCROLLBAR_WIDTH+2 : 4), drawY, GWidth-4-2-BND_SCROLLBAR_WIDTH-2, textHeight); //FIXME: not GHeight! @@ -718,42 +713,38 @@ void run (string bookFileName) { if (lidx >= 0 && lidx < laytext.lineCount) { drawY -= topY-laytext.line(lidx).y; vg.textAlign(NVGAlign.Left|NVGAlign.Baseline); - int lastSize = -1; LayFontStyle lastStyle; + int startx = (sbLeft ? 2+BND_SCROLLBAR_WIDTH+2 : 4); while (lidx < laytext.lineCount && drawY < GHeight) { auto ln = laytext.line(lidx); foreach (ref LayWord w; laytext.lineWords(lidx)) { - if (lastSize < 0 || lastStyle != w.style) { - lastStyle = w.style; - /+if (lastStyle.mono) { - if (lastStyle.italic && lastStyle.bold) vg.fontFaceId(monozFont); - else if (lastStyle.italic) vg.fontFaceId(monoiFont); - else if (lastStyle.bold) vg.fontFaceId(monobFont); - else vg.fontFaceId(monoFont); - } else+/ { - if (lastStyle.italic && lastStyle.bold) vg.fontFaceId(textzFont); - else if (lastStyle.italic) vg.fontFaceId(textiFont); - else if (lastStyle.bold) vg.fontFaceId(textbFont); - else vg.fontFaceId(textFont); + if (lastStyle != w.style) { + if (w.style.fontface != lastStyle.fontface) { + vg.fontFace(laytext.fontFace(w.style.fontface)); } - } - if (lastSize != w.style.fontsize) { - lastSize = w.style.fontsize; - vg.fontSize(lastSize); + vg.fontSize(w.style.fontsize); + auto c = NVGColor(w.style.color); + vg.fillColor(c); + //vg.strokeColor(c); + lastStyle = w.style; } // line highlighting - if (newYFade && newYLine == lidx) vg.fillColor(nvgLerpRGBA(u2c(colorText), u2c(colorTextHi), newYAlpha)); - vg.text((sbLeft ? 2+BND_SCROLLBAR_WIDTH+2 : 4)+w.x, drawY+ln.h+ln.desc, laytext.wordText(w)); + if (newYFade && newYLine == lidx) vg.fillColor(nvgLerpRGBA(colorText, colorTextHi, newYAlpha)); + vg.text(startx+w.x, drawY+ln.h+ln.desc, laytext.wordText(w)); + //TODO: draw lines over whitespace + if (lastStyle.underline) vg.rect(startx+w.x, drawY+ln.h+ln.desc+1, w.w, 1); + if (lastStyle.strike) vg.rect(startx+w.x, drawY+ln.h+ln.desc-w.asc/2, w.w, 1); + if (lastStyle.overline) vg.rect(startx+w.x, drawY+ln.h+ln.desc-w.asc-1, w.w, 1); version(debug_draw) { vg.fill(); vg.beginPath(); vg.strokeWidth(1); vg.strokeColor(nvgRGB(0, 0, 255)); - vg.rect((sbLeft ? 2+BND_SCROLLBAR_WIDTH+2 : 4)+w.x, drawY, w.w, w.h); + vg.rect(startx+w.x, drawY, w.w, w.h); vg.stroke(); vg.beginPath(); } - if (newYFade && newYLine == lidx) vg.fillColor(u2c(colorText)); + if (newYFade && newYLine == lidx) vg.fillColor(NVGColor(lastStyle.color)); } drawY += ln.h; ++lidx; @@ -763,11 +754,11 @@ void run (string bookFileName) { } // dim text if (!showShip) { - if ((colorDim&0xff000000) != 0) { + if (colorDim.a != 1) { //vg.scissor(0, 0, GWidth, GHeight); vg.resetScissor; vg.beginPath(); - vg.fillColor(u2ca(colorDim)); + vg.fillColor(colorDim); vg.rect(0, 0, GWidth, GHeight); vg.fill(); } diff --git a/xreadercfg.d b/xreadercfg.d index 99ef45f..60109e3 100644 --- a/xreadercfg.d +++ b/xreadercfg.d @@ -63,10 +63,11 @@ __gshared bool interAllowed = false; __gshared bool flagNanoAA = false; __gshared bool flagNanoSS = false; -__gshared uint colorDim = 0; -__gshared uint colorBack = 0x2a2a2a; -__gshared uint colorText = 0xff7f00; -__gshared uint colorTextHi = 0xffff00; +__gshared NVGColor colorDim = NVGColor(0, 0, 0, 0); +__gshared NVGColor colorBack = NVGColor(0x2a, 0x2a, 0x2a); +__gshared NVGColor colorText = NVGColor(0xff, 0x7f, 0x00); +__gshared NVGColor colorTextHi = NVGColor(0xff, 0xff, 0x00); +__gshared NVGColor colorTextHref = NVGColor(0, 0, 0x80); __gshared int uiFont, galmapFont; __gshared int textFont, textiFont, textbFont, textzFont; @@ -123,26 +124,6 @@ void loadEliteShips () { // ////////////////////////////////////////////////////////////////////////// // -auto u2ca (uint v) { - return nvgRGBA( - (v>>16)&0xff, - (v>>8)&0xff, - v&0xff, - (v>>24)&0xff, - ); -} - - -auto u2c (uint v) { - return nvgRGB( - (v>>16)&0xff, - (v>>8)&0xff, - v&0xff, - ); -} - - -// ////////////////////////////////////////////////////////////////////////// // VFile fwritef(A...) (VFile fl, string fmt, /*lazy*/ A args) { import std.string : format; auto s = format(fmt, args); @@ -178,10 +159,11 @@ void readConfig () { fl.fwritef("galmap-text-size=%s\n", fGalMapSize); fl.fwritef("scrollbar-on-left=%s\n", sbLeft); fl.fwritef("interference=%s\n", interAllowed); - fl.fwritef("color-dim=0x%08x\n", colorDim); - fl.fwritef("color-back=0x%08x\n", colorBack); - fl.fwritef("color-text=0x%08x\n", colorText); - fl.fwritef("color-text-hi=0x%08x\n", colorTextHi); + fl.fwritef("color-dim=0x%08x\n", colorDim.asUintHtml); + fl.fwritef("color-back=0x%08x\n", colorBack.asUintHtml); + fl.fwritef("color-text=0x%08x\n", colorText.asUintHtml); + fl.fwritef("color-text-hi=0x%08x\n", colorTextHi.asUintHtml); + fl.fwritef("color-text-href=0x%08x\n", colorTextHref.asUintHtml); fl.fwritef("nano-aa=%s\n", flagNanoAA); fl.fwritef("nano-ss=%s\n", flagNanoSS); fl.fwritef("justify-text=%s\n", optJustify); @@ -212,6 +194,7 @@ void readConfig () { "color-back", &colorBack, "color-text", &colorText, "color-text-hi", &colorTextHi, + "color-text-href", &colorTextHref, "nano-aa", &flagNanoAA, "nano-ss", &flagNanoSS, "justify-text", &optJustify, diff --git a/xreaderfmt.d b/xreaderfmt.d index d74cbd4..1cb13d5 100644 --- a/xreaderfmt.d +++ b/xreaderfmt.d @@ -90,19 +90,20 @@ public void formatBook (BookText book, LayText lay) { static void fixFont (LayText lay) { if (lay.fontStyle.italic) { - if (lay.fontStyle.bold) lay.fontStyle.fontface = lay.fontFace("textz"); - else lay.fontStyle.fontface = lay.fontFace("texti"); + if (lay.fontStyle.bold) lay.fontStyle.fontface = lay.fontFaceId("textz"); + else lay.fontStyle.fontface = lay.fontFaceId("texti"); } else if (lay.fontStyle.bold) { - if (lay.fontStyle.italic) lay.fontStyle.fontface = lay.fontFace("textz"); - else lay.fontStyle.fontface = lay.fontFace("textb"); + if (lay.fontStyle.italic) lay.fontStyle.fontface = lay.fontFaceId("textz"); + else lay.fontStyle.fontface = lay.fontFaceId("textb"); } else { - lay.fontStyle.fontface = lay.fontFace("text"); + lay.fontStyle.fontface = lay.fontFaceId("text"); } } static void setNormalStyle (LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText; + lay.fontStyle.color = colorText.asUint; lay.lineStyle.leftpad = 0; lay.lineStyle.rightpad = 0; lay.lineStyle.paraIndent = 3; @@ -113,6 +114,7 @@ public void formatBook (BookText book, LayText lay) { static void setTitleStyle (LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText+4; + lay.fontStyle.color = colorText.asUint; lay.lineStyle.leftpad = 0; lay.lineStyle.rightpad = 0; lay.lineStyle.paraIndent = 0; @@ -123,6 +125,7 @@ public void formatBook (BookText book, LayText lay) { static void setSubtitleStyle (LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText+2; + lay.fontStyle.color = colorText.asUint; lay.lineStyle.leftpad = 0; lay.lineStyle.rightpad = 0; lay.lineStyle.paraIndent = 0; @@ -134,8 +137,9 @@ public void formatBook (BookText book, LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText; lay.fontStyle.italic = true; - lay.lineStyle.leftpad = fsizeText*4; - lay.lineStyle.rightpad = fsizeText*4; + lay.fontStyle.color = colorText.asUint; + lay.lineStyle.leftpad = fsizeText*3; + lay.lineStyle.rightpad = fsizeText*3; lay.lineStyle.paraIndent = 3; if (optJustify) lay.lineStyle.setJustify; else lay.lineStyle.setLeft; fixFont(lay); @@ -145,6 +149,7 @@ public void formatBook (BookText book, LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText; lay.fontStyle.italic = true; + lay.fontStyle.color = colorText.asUint; lay.lineStyle.leftpad = lay.width/2; lay.lineStyle.rightpad = 0; lay.lineStyle.paraIndent = 0; @@ -156,7 +161,8 @@ public void formatBook (BookText book, LayText lay) { lay.fontStyle.flags = 0; lay.fontStyle.fontsize = fsizeText; lay.fontStyle.italic = true; - lay.lineStyle.leftpad = fsizeText*4; + lay.fontStyle.color = colorText.asUint; + lay.lineStyle.leftpad = fsizeText*3; lay.lineStyle.rightpad = 0; lay.lineStyle.paraIndent = 0; lay.lineStyle.setLeft; @@ -184,12 +190,14 @@ public void formatBook (BookText book, LayText lay) { void putParaContentInternal (Tag ct, int boldc=0, int italicc=0, int underc=0) { if (ct is null) return; + auto c = lay.fontStyle.color; + scope(exit) lay.fontStyle.color = c; switch (ct.name) { case "strong": ++boldc; lay.fontStyle.bold = true; break; case "emphasis": ++italicc; lay.fontStyle.italic = true; break; case "image": return; case "style": return; - case "a": ++underc; lay.fontStyle.underline = true; break; + case "a": ++underc; lay.fontStyle.underline = true; lay.fontStyle.color = colorTextHref.asUint; break; case "": lay.put(ct.text); return; default: badTag(ct); } @@ -473,6 +481,7 @@ void reformatThreadFn (Tid ownerTid) { //writeln("layouting..."); auto stt = MonoTime.currTime; auto lay = new LayText(laf, maxWidth); + lay.fontStyle.color = colorText.asUint; book.formatBook(lay); -- 2.11.4.GIT