ICU-5923 need to map from physical to logical when copying RTL char indices.

X-SVN-Rev: 22721
This commit is contained in:
Eric Mader 2007-09-29 00:55:19 +00:00
parent 6221451d1a
commit 48cc4bf0aa
5 changed files with 185 additions and 16 deletions

View file

@ -82,9 +82,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genrb", "..\tools\genrb\gen
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gentest", "..\tools\gentest\gentest.vcproj", "{77C78066-746F-4EA6-B3FE-B8C8A4A97891}"
ProjectSection(ProjectDependencies) = postProject
{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genuca", "..\tools\genuca\genuca.vcproj", "{86829694-A375-4C58-B4EA-96EF514E3225}"
@ -232,11 +232,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genctd", "..\tools\genctd\g
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "letest", "..\test\letest\letest.vcproj", "{67351485-4D18-4245-BE39-A7EF0675ACD2}"
ProjectSection(ProjectDependencies) = postProject
{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
{37FC2C7F-1904-4811-8955-2F478830EAD1} = {37FC2C7F-1904-4811-8955-2F478830EAD1}
{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
{C920062A-0647-4553-A3B2-37C58065664B} = {C920062A-0647-4553-A3B2-37C58065664B}
{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icuswap", "..\tools\icuswap\icuswap.vcproj", "{39690C2A-AD89-45E4-893A-899496B85785}"

View file

@ -971,8 +971,11 @@ void ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_in
glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph];
}
} else {
for (outGlyph = 0, inGlyph = rightGlyph - 1; inGlyph >= leftGlyph; inGlyph -= 1, outGlyph += 1) {
glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph];
// Because fGlyphToCharMap is stored in logical order to facilitate line breaking,
// we need to map the physical glyph indices to logical indices while we copy the
// character indices.
for (outGlyph = glyphCount - 1, inGlyph = rightGlyph - 1; inGlyph >= leftGlyph; inGlyph -= 1, outGlyph -= 1) {
glyphToCharMap[outGlyph] = fGlyphToCharMap[fGlyphCount - (glyphBase + inGlyph) - 1];
}
}

View file

@ -37,7 +37,7 @@ endif
CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/ctestfw -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/layout -I$(top_srcdir)
DEFS += -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"'
LIBS = $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) $(LIBCTESTFW) $(LIBICUTOOLUTIL) @LIBS@ @LIB_M@
LIBS = $(LIBICULX) $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) $(LIBCTESTFW) $(LIBICUTOOLUTIL) @LIBS@ @LIB_M@
COMMONOBJECTS = letsutil.o cmaps.o FontTableCache.o SimpleFontInstance.o PortableFontInstance.o
TESTOBJECTS = letest.o

View file

@ -14,7 +14,10 @@
#include "layout/LETypes.h"
#include "layout/LEScripts.h"
#include "loengine.h"
#include "layout/loengine.h"
#include "layout/playout.h"
#include "layout/plruns.h"
#include "cfonts.h"
@ -478,12 +481,94 @@ static void U_CALLCONV DataDrivenTest(void)
readTestFile(testFilePath, doTestCase);
}
/*
* From ticket:5923:
*
* Build a pl_paragraph with all Arabic text. Break it into multiple lines
* and make sure that the charToGlyph map for each run in each line is correct.
*
* Since the whole paragraph is right to left, we can expect the character indices,
* when read from right to left, to in order.
*
* Note: it might be a good idea to also check the glyphs and positions for each run,
* that we get the expected number of runs per line and that the line breaks are where
* we expect them to be. Really, it would be a good idea to make a whole test suite
* for pl_paragraph.
*/
static void U_CALLCONV GlyphToCharTest(void)
{
LEErrorCode status = LE_NO_ERROR;
le_font *font;
pl_fontRuns *fontRuns;
pl_paragraph *paragraph;
const pl_line *line;
LEUnicode chars[] = {
0x0627, 0x0644, 0x0629, 0x0020, 0x0627, 0x0644, 0x0635, 0x063A, 0x064A, 0x0631, 0x0629
};
le_int32 charCount = LE_ARRAY_SIZE(chars);
le_int32 charIndex = 0, lineNumber = 1;
le_int32 run, i;
const float lineWidth = 72;
font = le_simpleFontOpen(12, &status);
if (LE_FAILURE(status)) {
log_err("le_simpleFontOpen(12, &status) failed");
goto finish;
}
fontRuns = pl_openEmptyFontRuns(0);
pl_addFontRun(fontRuns, font, charCount);
paragraph = pl_create(chars, charCount, fontRuns, NULL, NULL, NULL, 0, FALSE, &status);
pl_closeFontRuns(fontRuns);
if (LE_FAILURE(status)) {
log_err("pl_create failed.");
goto close_font;
}
pl_reflow(paragraph);
while ((line = pl_nextLine(paragraph, lineWidth)) != NULL) {
le_int32 runCount = pl_countLineRuns(line);
for(run = 0; run < runCount; run += 1) {
const pl_visualRun *visualRun = pl_getLineVisualRun(line, run);
const le_int32 glyphCount = pl_getVisualRunGlyphCount(visualRun);
const le_int32 *glyphToCharMap = pl_getVisualRunGlyphToCharMap(visualRun);
for(i = glyphCount - 1; i >= 0; i -= 1) {
if (glyphToCharMap[i] != charIndex) {
log_err("Bad glyph to char index for glyph %d on line %d: expected %d, got %d\n",
i, lineNumber, charIndex, glyphToCharMap[i]);
goto close_paragraph; // once there's one error, we can't count on anything else...
}
charIndex += 1;
}
}
lineNumber += 1;
}
close_paragraph:
pl_close(paragraph);
close_font:
le_fontClose(font);
finish:
return;
}
U_CFUNC void addCTests(TestNode **root)
{
addTest(root, &ParamTest, "c_api/ParameterTest");
addTest(root, &FactoryTest, "c_api/FactoryTest");
addTest(root, &AccessTest, "c_layout/AccessTest");
addTest(root, &DataDrivenTest, "c_layout/DataDrivenTest");
addTest(root, &ParamTest, "c_api/ParameterTest");
addTest(root, &FactoryTest, "c_api/FactoryTest");
addTest(root, &AccessTest, "c_layout/AccessTest");
addTest(root, &DataDrivenTest, "c_layout/DataDrivenTest");
addTest(root, &GlyphToCharTest, "c_paragraph/GlyphToCharTest");
}

View file

@ -23,6 +23,9 @@
#include "layout/LEScripts.h"
#include "layout/LayoutEngine.h"
#include "layout/ParagraphLayout.h"
#include "layout/RunArrays.h"
#include "PortableFontInstance.h"
#include "SimpleFontInstance.h"
@ -715,13 +718,90 @@ free_c_strings:
}
U_CDECL_END
U_CDECL_BEGIN
/*
* From ticket:5923:
*
* Build a ParagraphLayout with all Arabic text. Break it into multiple lines
* and make sure that the charToGlyph map for each run in each line is correct.
*
* Since the whole paragraph is right to left, we can expect the character indices,
* when read from right to left, to in order.
*
* Note: it might be a good idea to also check the glyphs and positions for each run,
* that we get the expected number of runs per line and that the line breaks are where
* we expect them to be. Really, it would be a good idea to make a whole test suite
* for ParagraphLayout.
*/
static void U_CALLCONV GlyphToCharTest(void)
{
LEErrorCode status = LE_NO_ERROR;
LEFontInstance *font;
FontRuns fontRuns(0);
ParagraphLayout *paragraphLayout;
const ParagraphLayout::Line *line;
LEUnicode chars[] = {
0x0627, 0x0644, 0x0629, 0x0020, 0x0627, 0x0644, 0x0635, 0x063A, 0x064A, 0x0631, 0x0629
};
le_int32 charCount = LE_ARRAY_SIZE(chars);
le_int32 charIndex = 0, lineNumber = 1;
const float lineWidth = 72;
font = new SimpleFontInstance(12, status);
if (LE_FAILURE(status)) {
goto finish;
}
fontRuns.add(font, charCount);
paragraphLayout = new ParagraphLayout(chars, charCount, &fontRuns, NULL, NULL, NULL, 0, FALSE, status);
if (LE_FAILURE(status)) {
goto close_font;
}
paragraphLayout->reflow();
while ((line = paragraphLayout->nextLine(lineWidth)) != NULL) {
le_int32 runCount = line->countRuns();
for(le_int32 run = 0; run < runCount; run += 1) {
const ParagraphLayout::VisualRun *visualRun = line->getVisualRun(run);
le_int32 glyphCount = visualRun->getGlyphCount();
const le_int32 *glyphToCharMap = visualRun->getGlyphToCharMap();
for(le_int32 i = glyphCount - 1; i >= 0; i -= 1) {
if (glyphToCharMap[i] != charIndex) {
log_err("Bad glyph to char index for glyph %d on line %d: expected %d, got %d\n",
i, lineNumber, charIndex, glyphToCharMap[i]);
goto close_paragraph; // once there's one error, we can't count on anything else...
}
charIndex += 1;
}
}
lineNumber += 1;
}
close_paragraph:
delete paragraphLayout;
close_font:
delete font;
finish:
return;
}
U_CDECL_END
static void addAllTests(TestNode **root)
{
addTest(root, &ScriptTest, "api/ScriptTest");
addTest(root, &ParamTest, "api/ParameterTest");
addTest(root, &FactoryTest, "api/FactoryTest");
addTest(root, &AccessTest, "layout/AccessTest");
addTest(root, &DataDrivenTest, "layout/DataDrivenTest");
addTest(root, &ScriptTest, "api/ScriptTest");
addTest(root, &ParamTest, "api/ParameterTest");
addTest(root, &FactoryTest, "api/FactoryTest");
addTest(root, &AccessTest, "layout/AccessTest");
addTest(root, &DataDrivenTest, "layout/DataDrivenTest");
addTest(root, &GlyphToCharTest, "paragraph/GlyphToCharTest");
addCTests(root);
}