View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0015736 | Scribus | Typography | public | 2019-07-10 14:44 | 2019-07-30 21:27 |
Reporter | mujeebcpy | Assigned To | jghali | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | gnulinux | OS | kubuntu | OS Version | 19.04 |
Product Version | 1.5.4.svn | ||||
Fixed in Version | 1.5.5.svn | ||||
Summary | 0015736: Modifying character horizontal scale produces bad result on Malayalam text | ||||
Description | problem in scaling width of characters. when Unicode fonts (Malayalam, India) scaled all proportion of the fonts get distorted. hyphenation and rendering is perfect. only facing issue while scaling width. it render correctly in 100 %. cant reduce or increase the horizontal width. | ||||
Steps To Reproduce | ജോലിക്കാരായ കോഴികള് copy the above text to scribus select any font from http://smc.org.in/fonts or use Noto Sans Malayalam adjust the scaling width from advanced settings under text properties | ||||
Additional Information | this is specific to Malayalam unicode, a language in Kerala State, India. | ||||
Tags | patch, Text Distances | ||||
Patch | Yes | ||||
|
|
|
here is another screenshot that shows how the glyph are scaled but the space used for the glyphs is not (always) expanded |
|
try this patch. I had local changes to pdflib_core.cpp, but it should still apply malayalam-bug.diff (844 bytes)
Index: pdflib_core.cpp =================================================================== --- pdflib_core.cpp (revision 22991) +++ pdflib_core.cpp (working copy) @@ -249,7 +249,7 @@ } } } - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } Index: text/screenpainter.cpp =================================================================== --- text/screenpainter.cpp (revision 22991) +++ text/screenpainter.cpp (working copy) @@ -82,8 +82,8 @@ cairo_set_font_size(cr, fontSize()); double current_x = 0.0; + cairo_scale(cr, gc.scaleH(), gc.scaleV()); for (const GlyphLayout& gl : gc.glyphs()) { - cairo_scale(cr, gl.scaleH, gl.scaleV); cairo_glyph_t glyph = { gl.glyph, gl.xoffset + current_x, gl.yoffset }; cairo_show_glyphs(cr, &glyph, 1); current_x += gl.xadvance; |
|
did this patch is applicable in 1.5.5 too? i accidentally selected 15.4 while the bug is registered. im using 1.5.5 svn |
|
hi @mujeebcpy , all patches are made for the current code... : - ) |
|
Dear @avox and @ale, I tested the fix and working perfectly. Actually this amazed me that the solution was quick and fast. Thank you guys for fantastic response. I am attaching the recording of the output. |
|
@avox, please check the rendering is consistent when control characters are displayed. Your patch modify a single code path, so I doubt rendering is the same when control character display is enabled. |
|
Hi Jean, you are correct that this needs checking. But I assume that it doesn't matter because the bug only appeared when a glyph cluster had more than one glyph, which doesn't happen for control characters. In the PDF code I also neglected the codepaths for xforms and glyph outlines, so that needs checking, too. In the long run I'd like to get rid of the plethora of scaleH and scaleV attributes. They either copy each other or default to 1. Proposal: - keep scaleH ad scaleV in CharStyle with same usage as before - replace scaleH() and scaleV() in GlyphCluster with stretch(). The shaper is responsible to apply the CharStyle attributes like this: glyphCluster.fontSize = charStyle.fontSize * charStyle.scaleV; glyphCluster.stretch = charsStyle.scaleH / charStyle.scaleV; use stretch() wherever GlyphCluster.scaleH() where used before, and 1 where GlyphCluster.scaleV() was used - as far as I can tell, GlyphLayout.scaleH/scaleV are always the same as in the containing GlyphRun, so use that instead - for special cases, we could rename GlyphLayout.scaleH/scaleV to synthScaleH/synthScaleV and default both to 1. But I don't think they would be needed any more. |
|
Oh, and the PostScript output also needs checking. Anything that implements TextLayoutPainter. |
|
>> But I assume that it doesn't matter because the bug only appeared when a glyph cluster had more than one glyph, which doesn't happen for control characters. Well in fact it matters because on Windows, Fontconfig is not used. So CAIRO_HAS_FC_FONT is undefined or null, hence making your current fix ineffective on Windows. |
|
Here is a more complete patch which includes the necessary modifications for PDF, PS, SVG, and XPS export. Please test. The approach to fix the issue is slightly different to avoid some rendering differences with docs using Latin languages. There is still some brokenness in the XPS export but apparently this is not related to the patch itself: a routine supposed to merge XPS "Glyphs" elements apparently produces unexpected results. 15736_malayam_char_width.patch (12,345 bytes)
Index: scribus/pdflib_core.cpp =================================================================== --- scribus/pdflib_core.cpp (revision 23071) +++ scribus/pdflib_core.cpp (working copy) @@ -154,7 +154,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -249,7 +249,7 @@ } } } - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } @@ -263,7 +263,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -290,7 +290,7 @@ m_pathBuffer += "q\n"; m_pathBuffer += transformToStr(transform) + " cm\n"; - m_pathBuffer += FToStr(fontSize()) + " 0 0 " + FToStr(fontSize()) + " " + FToStr(x() + gl.xoffset) + " " + FToStr((y() - fontSize() + gl.yoffset) * -1) + " cm\n"; + m_pathBuffer += FToStr(fontSize()) + " 0 0 " + FToStr(fontSize()) + " " + FToStr(x() + gl.xoffset + current_x) + " " + FToStr((y() - fontSize() + gl.yoffset) * -1) + " cm\n"; if (gc.scaleV() != 1.0) m_pathBuffer += "1 0 0 1 0 " + FToStr(((fontSize() - fontSize() * (gc.scaleV())) / fontSize()) * -1) + " cm\n"; @@ -456,7 +456,7 @@ } } } - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } Index: scribus/plugins/export/svgexplugin/svgexplugin.cpp =================================================================== --- scribus/plugins/export/svgexplugin/svgexplugin.cpp (revision 23071) +++ scribus/plugins/export/svgexplugin/svgexplugin.cpp (working copy) @@ -1163,7 +1163,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -1178,7 +1178,7 @@ glyph.setAttribute("style", fill + stroke); m_elem.appendChild(glyph); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } @@ -1192,7 +1192,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -1210,7 +1210,7 @@ glyph.setAttribute("style", fill + stroke); m_elem.appendChild(glyph); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } Index: scribus/plugins/export/xpsexport/xpsexplugin.cpp =================================================================== --- scribus/plugins/export/xpsexport/xpsexplugin.cpp (revision 23071) +++ scribus/plugins/export/xpsexport/xpsexplugin.cpp (working copy) @@ -838,15 +838,15 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } indices += QString("%1,%2,%3,%4;").arg(gl.glyph) - .arg(((gl.xadvance + current_x) * m_xps->conversionFactor) / size * 100) + .arg(((gl.xadvance * gl.scaleH + current_x) * m_xps->conversionFactor) / size * 100) .arg((-gl.xoffset * m_xps->conversionFactor) / size * 100) .arg((-gl.yoffset * m_xps->conversionFactor) / size * 100); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } indices.chop(1); glyph.setAttribute("Indices", QString("%1%2").arg(gcMap, indices)); @@ -863,7 +863,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -886,9 +886,9 @@ glyph.setAttribute("StrokeThickness", m_xps->FToStr(strokeWidth() * m_xps->conversionFactor)); glyph.setAttribute("Stroke", m_xps->SetColor(strokeColor().color, strokeColor().shade, 0)); m_group.appendChild(glyph); - qDebug() << "StrokeWidth XPS" << strokeWidth(); + //qDebug() << "StrokeWidth XPS" << strokeWidth(); } - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } } @@ -1090,11 +1090,44 @@ first = true; } grp2.appendChild(txtGrp.cloneNode(true)); + continue; } + + if (first) + { + RenderTransform = txtGrp.attribute("RenderTransform"); + FontRenderingEmSize = txtGrp.attribute("FontRenderingEmSize"); + FontUri = txtGrp.attribute("FontUri"); + Fill = txtGrp.attribute("Fill"); + OriginX = txtGrp.attribute("OriginX"); + OriginY = txtGrp.attribute("OriginY"); + Indices = txtGrp.attribute("Indices"); + UnicodeString = txtGrp.attribute("UnicodeString"); + glyph = p_docu.createElement("Glyphs"); + glyph.setAttribute("RenderTransform", RenderTransform); + glyph.setAttribute("BidiLevel", "0"); + glyph.setAttribute("StyleSimulations", "None"); + glyph.setAttribute("FontRenderingEmSize", FontRenderingEmSize); + glyph.setAttribute("FontUri", FontUri); + glyph.setAttribute("Fill", Fill); + glyph.setAttribute("OriginX", OriginX); + glyph.setAttribute("OriginY", OriginY); + glyph.setAttribute("Indices", Indices); + glyph.setAttribute("UnicodeString", UnicodeString); + grp2.appendChild(glyph); + first = false; + } else { - if (first) + if ((RenderTransform == txtGrp.attribute("RenderTransform")) && (FontRenderingEmSize == txtGrp.attribute("FontRenderingEmSize")) && (FontUri == txtGrp.attribute("FontUri")) && (OriginY == txtGrp.attribute("OriginY")) && (Fill == txtGrp.attribute("Fill"))) { + Indices.append(";" + txtGrp.attribute("Indices")); + UnicodeString.append(txtGrp.attribute("UnicodeString")); + } + else + { + glyph.setAttribute("Indices", Indices); + glyph.setAttribute("UnicodeString", UnicodeString); RenderTransform = txtGrp.attribute("RenderTransform"); FontRenderingEmSize = txtGrp.attribute("FontRenderingEmSize"); FontUri = txtGrp.attribute("FontUri"); @@ -1117,46 +1150,13 @@ grp2.appendChild(glyph); first = false; } - else - { - if ((RenderTransform == txtGrp.attribute("RenderTransform")) && (FontRenderingEmSize == txtGrp.attribute("FontRenderingEmSize")) && (FontUri == txtGrp.attribute("FontUri")) && (OriginY == txtGrp.attribute("OriginY")) && (Fill == txtGrp.attribute("Fill"))) - { - Indices.append(";" + txtGrp.attribute("Indices")); - UnicodeString.append(txtGrp.attribute("UnicodeString")); - } - else - { - glyph.setAttribute("Indices", Indices); - glyph.setAttribute("UnicodeString", UnicodeString); - RenderTransform = txtGrp.attribute("RenderTransform"); - FontRenderingEmSize = txtGrp.attribute("FontRenderingEmSize"); - FontUri = txtGrp.attribute("FontUri"); - Fill = txtGrp.attribute("Fill"); - OriginX = txtGrp.attribute("OriginX"); - OriginY = txtGrp.attribute("OriginY"); - Indices = txtGrp.attribute("Indices"); - UnicodeString = txtGrp.attribute("UnicodeString"); - glyph = p_docu.createElement("Glyphs"); - glyph.setAttribute("RenderTransform", RenderTransform); - glyph.setAttribute("BidiLevel", "0"); - glyph.setAttribute("StyleSimulations", "None"); - glyph.setAttribute("FontRenderingEmSize", FontRenderingEmSize); - glyph.setAttribute("FontUri", FontUri); - glyph.setAttribute("Fill", Fill); - glyph.setAttribute("OriginX", OriginX); - glyph.setAttribute("OriginY", OriginY); - glyph.setAttribute("Indices", Indices); - glyph.setAttribute("UnicodeString", UnicodeString); - grp2.appendChild(glyph); - first = false; - } - } - if (txtGrp == grp.lastChildElement()) - { - glyph.setAttribute("Indices", Indices); - glyph.setAttribute("UnicodeString", UnicodeString); - } } + + if (txtGrp == grp.lastChildElement()) + { + glyph.setAttribute("Indices", Indices); + glyph.setAttribute("UnicodeString", UnicodeString); + } } parentElem.appendChild(grp2); } Index: scribus/pslib.cpp =================================================================== --- scribus/pslib.cpp (revision 23071) +++ scribus/pslib.cpp (working copy) @@ -115,7 +115,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -129,7 +129,7 @@ m_ps->PS_showSub(gl.glyph, m_ps->FontSubsetMap[font().scName()], fontSize(), false); m_ps->PS_restore(); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } m_ps->PS_restore(); } @@ -156,7 +156,7 @@ { if (gl.glyph >= ScFace::CONTROL_GLYPHS) { - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; continue; } @@ -166,11 +166,17 @@ chma.scale((fontSize() * gc.scaleH()) / 10.0, (fontSize() * gc.scaleV()) / 10.0); gly.map(chma); m_ps->PS_translate(gl.xoffset + current_x, -(fontSize() - fontSize() * gc.scaleV()) - gl.yoffset); - if (gc.scaleH() != 1.0 || gc.scaleV() != 1.0) - m_ps->PS_scale(gc.scaleH(), gc.scaleV()); + if (fill) + { + m_ps->PS_save(); + if (gc.scaleH() != 1.0 || gc.scaleV() != 1.0) + m_ps->PS_scale(gc.scaleH(), gc.scaleV()); m_ps->putColorNoDraw(fillColor().color, fillColor().shade); - m_ps->PS_showSub(gl.glyph, m_ps->FontSubsetMap[font().scName()], fontSize(), false); + m_ps->PS_showSub(gl.glyph, m_ps->FontSubsetMap[font().scName()], fontSize(), false); + m_ps->PS_restore(); + } + m_ps->SetColor(strokeColor().color, strokeColor().shade, &h, &s, &v, &k); m_ps->PS_setcmykcolor_stroke(h, s, v, k); m_ps->SetClipPath(gly, true); @@ -178,7 +184,7 @@ m_ps->putColor(strokeColor().color, strokeColor().shade, false); m_ps->PS_restore(); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } m_ps->PS_restore(); Index: scribus/scpageoutput.cpp =================================================================== --- scribus/scpageoutput.cpp (revision 23071) +++ scribus/scpageoutput.cpp (working copy) @@ -1002,7 +1002,7 @@ if (outline.size() > 3) m_painter->fillPath(); m_painter->restore(); - m_painter->translate(gl.xadvance, 0.0); + m_painter->translate(gl.xadvance * gl.scaleH, 0.0); } m_painter->setFillMode(fm); @@ -1030,9 +1030,11 @@ m_painter->translate(gl.xoffset + current_x, -(fontSize() * gc.scaleV()) + gl.yoffset); FPointArray outline = font().glyphOutline(gl.glyph); - double scaleH = gc.scaleH() * fontSize() / 10.0; - double scaleV = gc.scaleV() * fontSize() / 10.0; - m_painter->scale(scaleH, scaleV); + double scaleH = gl.scaleH * fontSize() / 10.0; + double scaleV = gl.scaleV * fontSize() / 10.0; + QTransform trans; + trans.scale(scaleH, scaleV); + outline.map(trans); m_painter->setupPolygon(&outline, true); if (outline.size() > 3) { @@ -1040,7 +1042,7 @@ m_painter->strokePath(); } m_painter->restore(); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } m_painter->setFillRule(fr); Index: scribus/text/screenpainter.cpp =================================================================== --- scribus/text/screenpainter.cpp (revision 23071) +++ scribus/text/screenpainter.cpp (working copy) @@ -86,7 +86,7 @@ cairo_scale(cr, gl.scaleH, gl.scaleV); cairo_glyph_t glyph = { gl.glyph, gl.xoffset + current_x, gl.yoffset }; cairo_show_glyphs(cr, &glyph, 1); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } m_painter->restore(); return; @@ -227,7 +227,7 @@ if (outline.size() > 3) m_painter->fillPath(); m_painter->restore(); - m_painter->translate(gl.xadvance, 0.0); + m_painter->translate(gl.xadvance * gl.scaleH, 0.0); } } m_painter->setFillRule(fr); @@ -239,6 +239,7 @@ { if (fill) drawGlyph(gc); + m_painter->save(); bool fr = m_painter->fillRule(); m_painter->setFillRule(false); @@ -249,6 +250,7 @@ { m_painter->save(); m_painter->translate(gl.xoffset + current_x, - (fontSize() * gl.scaleV) + gl.yoffset ); + FPointArray outline = font().glyphOutline(gl.glyph); double scaleHv = gl.scaleH * fontSize() / 10.0; double scaleVv = gl.scaleV * fontSize() / 10.0; @@ -262,12 +264,11 @@ m_painter->strokePath(); } m_painter->restore(); - current_x += gl.xadvance; + current_x += gl.xadvance * gl.scaleH; } m_painter->setFillRule(fr); m_painter->restore(); - } void ScreenPainter::drawLine(QPointF start, QPointF end) |
|
@jghali, Thank you for consider this bug as serious. I will apply this path and test now. Unfortunately I don't have a Windows system to test the output. I will test on Fedora and Ubuntu. |
|
@jghali, @avox I applied the new patch and built the scribus again. but it is not working in the screenpainter. the pdf output is OK. while checking two patches i found that in @avox patch the line `cairo_scale(cr, gc.scaleH(), gc.scaleV());` is moved above for loop. and it is working perfectly on the screen. but in new patch `current_x += gl.xadvance * gl.scaleH;` this line is modified but it has no effects. still buggy in the screen. The Svg output is all messed up. CLT rendering is not working. |
|
The svg output of scribus file. |
|
There is also another issue with Dropcap. multiglif Dropcap isnt working. but in the previous fix helped to reduce the issue. |
|
Thanks for the feedback. So for the Linux side, I reverted to avox approach. For the rest I've kept the patch as is, except for the PDF export where I fixed some additional consistencies issues between screen and PDF export when character outline effect is enabled. The modifications have now been committed, so you can get the updated code directly from svn. As for svg export, I do not see an issue with my test documents: the display in Firefox or Microsoft Edge is consistent with the display in scribus. So if you see an issue with the way text is exported to svg, I would need your test document. |
|
As for me, this specific issue is fixed. If you have a specific problem with SVG export, please open a separate issue. |
|
Hi, i pulled and built. now everything works fine. svg out also rendering correctly. thanks for the help and fix. attaching svg and scribus screenshots |
Date Modified | Username | Field | Change |
---|---|---|---|
2019-07-10 14:44 | mujeebcpy | New Issue | |
2019-07-10 14:44 | mujeebcpy | File Added: Scribus-text-scale.gif | |
2019-07-10 14:44 | mujeebcpy | Tag Attached: Text Distances | |
2019-07-10 16:05 | ale | File Added: noto-malayam-char-width.gif | |
2019-07-10 16:05 | ale | Note Added: 0046372 | |
2019-07-10 22:37 | avox | File Added: malayalam-bug.diff | |
2019-07-10 22:37 | avox | Note Added: 0046375 | |
2019-07-10 23:33 | mujeebcpy | Note Added: 0046376 | |
2019-07-11 05:48 | ale | Note Added: 0046377 | |
2019-07-11 06:37 | ranjithsiji | File Added: Peek 2019-07-11 11-58.gif | |
2019-07-11 06:37 | ranjithsiji | Note Added: 0046378 | |
2019-07-11 07:44 | ale | Summary | Scaling width of charecters in unicode (Malayalam, India) => [PATCH] Scaling width of charecters in unicode (Malayalam, India) |
2019-07-11 07:44 | ale | Patch | No => Yes |
2019-07-11 07:44 | ale | Tag Attached: patch | |
2019-07-11 08:58 | jghali | Summary | [PATCH] Scaling width of charecters in unicode (Malayalam, India) => [PATCH] Scaling width of characters in unicode (Malayalam, India) |
2019-07-11 09:31 | jghali | Note Added: 0046380 | |
2019-07-11 10:57 | avox | Note Added: 0046381 | |
2019-07-11 11:20 | avox | Note Added: 0046382 | |
2019-07-11 22:06 | jghali | Note Added: 0046383 | |
2019-07-12 17:13 | jghali | File Added: 15736_malayam_char_width.patch | |
2019-07-12 17:13 | jghali | Note Added: 0046385 | |
2019-07-13 01:38 | ranjithsiji | Note Added: 0046386 | |
2019-07-13 07:55 | mujeebcpy | File Added: scribus-scale-2ndpatch.png | |
2019-07-13 07:55 | mujeebcpy | Note Added: 0046387 | |
2019-07-13 07:56 | mujeebcpy | File Added: svgscribus.png | |
2019-07-13 07:56 | mujeebcpy | Note Added: 0046388 | |
2019-07-13 08:00 | mujeebcpy | Note Added: 0046389 | |
2019-07-13 21:18 | jghali | Note Added: 0046390 | |
2019-07-13 21:18 | jghali | Priority | urgent => normal |
2019-07-13 21:20 | jghali | Summary | [PATCH] Scaling width of characters in unicode (Malayalam, India) => Modifying character horizontal scale produces bad result on Malayalam text |
2019-07-14 18:55 | jghali | Assigned To | => jghali |
2019-07-14 18:55 | jghali | Status | new => resolved |
2019-07-14 18:55 | jghali | Resolution | open => fixed |
2019-07-14 18:55 | jghali | Fixed in Version | => 1.5.5.svn |
2019-07-14 18:55 | jghali | Note Added: 0046391 | |
2019-07-15 08:46 | mujeebcpy | File Added: svgout.png | |
2019-07-15 08:46 | mujeebcpy | File Added: scribus_scale.png | |
2019-07-15 08:46 | mujeebcpy | Note Added: 0046392 | |
2019-07-30 21:27 | cbradney | Status | resolved => closed |