ICU-5565 Merge loengine branch to trunk!
X-SVN-Rev: 21808
This commit is contained in:
parent
ac329166b4
commit
b2dc4eced5
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -88,6 +88,9 @@ icu4c/source/i18n/persncal.cpp -text
|
||||
icu4c/source/i18n/persncal.h -text
|
||||
icu4c/source/i18n/reldtfmt.cpp -text
|
||||
icu4c/source/i18n/reldtfmt.h -text
|
||||
icu4c/source/samples/layout/cgnomelayout.c -text
|
||||
icu4c/source/samples/layout/gnomeglue.cpp -text
|
||||
icu4c/source/samples/layout/gnomeglue.h -text
|
||||
icu4c/source/samples/ucnv/data02.bin -text
|
||||
icu4c/source/test/compat/Makefile.in -text
|
||||
icu4c/source/test/compat/readme.txt -text
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998 - 2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998 - 2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -34,6 +34,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
|
||||
|
||||
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
|
||||
glyphIterator->setCursiveEntryPoint(entryAnchor);
|
||||
} else {
|
||||
//glyphIterator->clearCursiveEntryPoint();
|
||||
}
|
||||
|
||||
if (exitOffset != 0) {
|
||||
@ -41,6 +43,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
|
||||
|
||||
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
|
||||
glyphIterator->setCursiveExitPoint(exitAnchor);
|
||||
} else {
|
||||
//glyphIterator->clearCursiveExitPoint();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -274,6 +274,36 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float
|
||||
glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
|
||||
}
|
||||
|
||||
void GlyphIterator::clearCursiveEntryPoint()
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->clearEntryPoint(position);
|
||||
}
|
||||
|
||||
void GlyphIterator::clearCursiveExitPoint()
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->clearExitPoint(position);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
|
||||
{
|
||||
if (direction < 0) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -63,6 +63,8 @@ public:
|
||||
void setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
|
||||
float xAdvanceAdjust, float yAdvanceAdjust);
|
||||
|
||||
void clearCursiveEntryPoint();
|
||||
void clearCursiveExitPoint();
|
||||
void setCursiveEntryPoint(LEPoint &entryPoint);
|
||||
void setCursiveExitPoint(LEPoint &exitPoint);
|
||||
void setCursiveGlyph();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -46,6 +46,20 @@ const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &e
|
||||
return fEntryExitPoints[index].getExitPoint(exitPoint);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::clearEntryPoint(le_int32 index)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].clearEntryPoint();
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::clearExitPoint(le_int32 index)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].clearExitPoint();
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -72,6 +72,8 @@ private:
|
||||
LEPoint *getEntryPoint(LEPoint &entryPoint) const;
|
||||
LEPoint *getExitPoint(LEPoint &exitPoint) const;
|
||||
|
||||
inline void clearEntryPoint();
|
||||
inline void clearExitPoint();
|
||||
inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
|
||||
inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
|
||||
inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
|
||||
@ -126,6 +128,8 @@ public:
|
||||
inline void adjustXAdvance(le_int32 index, float xAdjustment);
|
||||
inline void adjustYAdvance(le_int32 index, float yAdjustment);
|
||||
|
||||
void clearEntryPoint(le_int32 index);
|
||||
void clearExitPoint(le_int32 index);
|
||||
void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
|
||||
void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
|
||||
void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
|
||||
@ -241,6 +245,16 @@ inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd()
|
||||
return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
|
||||
{
|
||||
fFlags &= ~EEF_HAS_ENTRY_POINT;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
|
||||
{
|
||||
fFlags &= ~EEF_HAS_EXIT_POINT;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
if (baselineIsLogicalEnd) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -12,7 +12,10 @@
|
||||
#endif
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
#include "unicode/uobject.h"
|
||||
#endif
|
||||
|
||||
#ifdef LE_USE_CMEMORY
|
||||
#include "cmemory.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "MorphTables.h"
|
||||
|
||||
#include "DefaultCharMapper.h"
|
||||
@ -86,6 +87,37 @@ CharSubstitutionFilter::~CharSubstitutionFilter()
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
class CanonMarkFilter : public UMemory, public LEGlyphFilter
|
||||
{
|
||||
private:
|
||||
const GlyphClassDefinitionTable *classDefTable;
|
||||
|
||||
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
|
||||
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
|
||||
|
||||
public:
|
||||
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
|
||||
virtual ~CanonMarkFilter();
|
||||
|
||||
virtual le_bool accept(LEGlyphID glyph) const;
|
||||
};
|
||||
|
||||
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
|
||||
{
|
||||
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
|
||||
}
|
||||
|
||||
CanonMarkFilter::~CanonMarkFilter()
|
||||
{
|
||||
// nothing to do?
|
||||
}
|
||||
|
||||
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
|
||||
{
|
||||
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
|
||||
|
||||
return glyphClass != 0;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
|
||||
|
||||
@ -279,7 +311,7 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y
|
||||
glyphStorage.setPosition(glyphCount, x, y, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
|
||||
void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
@ -291,6 +323,11 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
|
||||
return;
|
||||
}
|
||||
|
||||
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
|
||||
CanonMarkFilter filter(gdefTable);
|
||||
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
|
||||
if (fTypoFlags & 0x1) { /* kerning enabled */
|
||||
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#******************************************************************************
|
||||
#
|
||||
# Copyright (C) 1999-2006, International Business Machines
|
||||
# Copyright (C) 1999-2007, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#
|
||||
#******************************************************************************
|
||||
@ -132,10 +132,11 @@ KhmerReordering.o \
|
||||
TibetanLayoutEngine.o \
|
||||
TibetanReordering.o \
|
||||
HangulLayoutEngine.o \
|
||||
KernTable.o
|
||||
KernTable.o \
|
||||
loengine.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS= $(srcdir)/LayoutEngine.h $(srcdir)/LE*.h
|
||||
HEADERS= $(srcdir)/LayoutEngine.h $(srcdir)/LE*.h $(srcdir)/loengine.h
|
||||
|
||||
STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O))
|
||||
|
||||
|
@ -332,6 +332,19 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
||||
delete adjustments;
|
||||
}
|
||||
|
||||
LEGlyphID zwnj = fFontInstance->mapCharToGlyph(0x200C);
|
||||
LEGlyphID nbsp = fFontInstance->mapCharToGlyph(0x00A0);
|
||||
|
||||
for (le_int32 g = 0; g < glyphCount; g += 1) {
|
||||
LEGlyphID glyph = glyphStorage[g];
|
||||
|
||||
if (glyph == zwnj) {
|
||||
glyphStorage[g] = LE_SET_GLYPH(glyph, 0xFFFF);
|
||||
} else if (glyph == nbsp) {
|
||||
glyphStorage[g] = LE_SET_GLYPH(glyph, 0x0003);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Don't know why this is here...
|
||||
LE_DELETE_ARRAY(fFeatureTags);
|
||||
|
@ -369,6 +369,10 @@
|
||||
RelativePath=".\LigatureSubstSubtables.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loengine.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LookupProcessor.cpp"
|
||||
>
|
||||
@ -872,6 +876,19 @@
|
||||
RelativePath=".\LigatureSubstSubtables.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loengine.h"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LookupProcessor.h"
|
||||
>
|
||||
|
163
icu4c/source/layout/loengine.cpp
Normal file
163
icu4c/source/layout/loengine.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
#include "LayoutEngine.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C API for complex text layout.
|
||||
*/
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
U_CAPI le_engine * U_EXPORT2
|
||||
le_create(const le_font *font,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
le_int32 typo_flags,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LEFontInstance *fontInstance = (LEFontInstance *) font;
|
||||
|
||||
return (le_engine *) LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, typo_flags, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_close(le_engine *engine)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
delete le;
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
le_layoutChars(le_engine *engine,
|
||||
const LEUnicode chars[],
|
||||
le_int32 offset,
|
||||
le_int32 count,
|
||||
le_int32 max,
|
||||
le_bool rightToLeft,
|
||||
float x,
|
||||
float y,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return le->layoutChars(chars, offset, count, max, rightToLeft, x, y, *success);
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
le_getGlyphCount(le_engine *engine,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return le->getGlyphCount();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_getGlyphs(le_engine *engine,
|
||||
LEGlyphID glyphs[],
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->getGlyphs(glyphs, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_getCharIndices(le_engine *engine,
|
||||
le_int32 charIndices[],
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->getCharIndices(charIndices, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_getCharIndicesWithBase(le_engine *engine,
|
||||
le_int32 charIndices[],
|
||||
le_int32 indexBase,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->getCharIndices(charIndices, indexBase, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_getGlyphPositions(le_engine *engine,
|
||||
float positions[],
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->getGlyphPositions(positions, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_getGlyphPosition(le_engine *engine,
|
||||
le_int32 glyphIndex,
|
||||
float *x,
|
||||
float *y,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->getGlyphPosition(glyphIndex, *x, *y, *success);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
le_reset(le_engine *engine,
|
||||
LEErrorCode *success)
|
||||
{
|
||||
LayoutEngine *le = (LayoutEngine *) engine;
|
||||
|
||||
if (le == NULL) {
|
||||
*success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le->reset();
|
||||
}
|
223
icu4c/source/layout/loengine.h
Normal file
223
icu4c/source/layout/loengine.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LOENGINE_H
|
||||
#define __LOENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C API for complex text layout.
|
||||
* \internal
|
||||
*
|
||||
* This is a technology preview. The API may
|
||||
* change significantly.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The opaque type for a LayoutEngine.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
typedef void le_engine;
|
||||
|
||||
/**
|
||||
* The opaque type for a font instance.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
typedef void le_font;
|
||||
|
||||
/**
|
||||
* This function returns an le_engine capable of laying out text
|
||||
* in the given font, script and langauge. Note that the LayoutEngine
|
||||
* returned may be a subclass of LayoutEngine.
|
||||
*
|
||||
* @param font - the font of the text
|
||||
* @param scriptCode - the script of the text
|
||||
* @param languageCode - the language of the text
|
||||
* @param typo_flags - flags that control layout features like kerning and ligatures.
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @return an le_engine which can layout text in the given font.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_engine * U_EXPORT2
|
||||
le_create(const le_font *font,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
le_int32 typo_flags,
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function closes the given LayoutEngine. After
|
||||
* it returns, the le_engine is no longer valid.
|
||||
*
|
||||
* @param engine - the LayoutEngine to close.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_close(le_engine *engine);
|
||||
|
||||
/**
|
||||
* This routine will compute the glyph, character index and position arrays.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the characers are in a right to left directional run
|
||||
* @param x - the initial X position
|
||||
* @param y - the initial Y position
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph array
|
||||
*
|
||||
* Note: The glyph, character index and position array can be accessed
|
||||
* using the getter routines below.
|
||||
*
|
||||
* Note: If you call this function more than once, you must call the reset()
|
||||
* function first to free the glyph, character index and position arrays
|
||||
* allocated by the previous call.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
le_layoutChars(le_engine *engine,
|
||||
const LEUnicode chars[],
|
||||
le_int32 offset,
|
||||
le_int32 count,
|
||||
le_int32 max,
|
||||
le_bool rightToLeft,
|
||||
float x,
|
||||
float y,
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function returns the number of glyphs in the glyph array. Note
|
||||
* that the number of glyphs will be greater than or equal to the number
|
||||
* of characters used to create the LayoutEngine.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param success - output parameter set to an error code if the operation fails.
|
||||
*
|
||||
* @return the number of glyphs in the glyph array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
le_getGlyphCount(le_engine *engine,
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function copies the glyph array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold all
|
||||
* the glyphs.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param glyphs - the destiniation glyph array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_getGlyphs(le_engine *engine,
|
||||
LEGlyphID glyphs[],
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_getCharIndices(le_engine *engine,
|
||||
le_int32 charIndices[],
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param indexBase - an offset that will be added to each index.
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_getCharIndicesWithBase(le_engine *engine,
|
||||
le_int32 charIndices[],
|
||||
le_int32 indexBase,
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function copies the position array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold an
|
||||
* X and Y position for each glyph, plus an extra X and Y for the
|
||||
* advance of the last glyph.
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param positions - the destiniation position array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_getGlyphPositions(le_engine *engine,
|
||||
float positions[],
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function returns the X and Y position of the glyph at
|
||||
* the given index.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param engine - the LayoutEngine
|
||||
* @param glyphIndex - the index of the glyph
|
||||
*
|
||||
* Output parameters:
|
||||
* @param x - the glyph's X position
|
||||
* @param y - the glyph's Y position
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_getGlyphPosition(le_engine *engine,
|
||||
le_int32 glyphIndex,
|
||||
float *x,
|
||||
float *y,
|
||||
LEErrorCode *success);
|
||||
|
||||
/**
|
||||
* This function frees the glyph, character index and position arrays
|
||||
* so that the LayoutEngine can be reused to layout a different
|
||||
* characer array. (This function is also called by le_close)
|
||||
*
|
||||
* @param engine - the LayoutEngine
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
le_reset(le_engine *engine,
|
||||
LEErrorCode *success);
|
||||
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
#******************************************************************************
|
||||
#
|
||||
# Copyright (C) 1999-2005, International Business Machines
|
||||
# Copyright (C) 1999-2007, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#
|
||||
#******************************************************************************
|
||||
@ -62,7 +62,9 @@ LIBS = $(LIBICUUC) $(LIBICULE) $(DEFAULT_LIBS)
|
||||
|
||||
OBJECTS = ParagraphLayout.o \
|
||||
RunArrays.o \
|
||||
LXUtilities.o
|
||||
LXUtilities.o \
|
||||
playout.o \
|
||||
plruns.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS= $(srcdir)/layout/ParagraphLayout.h $(srcdir)/layout/RunArrays.h
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2003-2005, International Business Machines
|
||||
* Copyright (C) 2003-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
@ -502,6 +502,8 @@ protected:
|
||||
virtual void init(le_int32 capacity);
|
||||
virtual void grow(le_int32 capacity);
|
||||
|
||||
const Locale **fLocales;
|
||||
|
||||
private:
|
||||
|
||||
inline LocaleRuns();
|
||||
@ -513,8 +515,6 @@ private:
|
||||
* for ICU "poor man's RTTI".
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
const Locale **fLocales;
|
||||
};
|
||||
|
||||
inline LocaleRuns::LocaleRuns()
|
||||
|
458
icu4c/source/layoutex/layout/playout.h
Normal file
458
icu4c/source/layoutex/layout/playout.h
Normal file
@ -0,0 +1,458 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PLAYOUT_H
|
||||
#define __PLAYOUT_H
|
||||
|
||||
#include "unicode/ubidi.h"
|
||||
#include "layout/LETypes.h"
|
||||
#include "plruns.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C API for paragraph layout.
|
||||
* \internal
|
||||
*
|
||||
* This is a technology preview. The API may
|
||||
* change significantly.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The opaque type for a paragraph layout.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
typedef void pl_paragraph;
|
||||
|
||||
/**
|
||||
* The opaque type for a line in a paragraph layout.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
typedef void pl_line;
|
||||
|
||||
/**
|
||||
* The opaque type for a visual run in a line.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
typedef void pl_visualRun;
|
||||
|
||||
/**
|
||||
* Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified
|
||||
* as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset
|
||||
* are specified for each font run. The limit offset is the offset of the character immediately
|
||||
* after the font run.
|
||||
*
|
||||
* Clients can optionally specify directional runs and / or script runs. If these aren't specified
|
||||
* they will be computed.
|
||||
*
|
||||
* If any errors are encountered during construction, <code>status</code> will be set, and the object
|
||||
* will be set to be empty.
|
||||
*
|
||||
* @param chars is an array of the characters in the paragraph
|
||||
*
|
||||
* @param count is the number of characters in the paragraph.
|
||||
*
|
||||
* @param fontRuns a pointer to a <code>pl_fontRuns</code> object representing the font runs.
|
||||
*
|
||||
* @param levelRuns is a pointer to a <code>pl_valueRuns</code> object representing the directional levels.
|
||||
* If this pointer in <code>NULL</code> the levels will be determined by running the Unicde
|
||||
* Bidi algorithm.
|
||||
*
|
||||
* @param scriptRuns is a pointer to a <code>pl_valueRuns</code> object representing script runs.
|
||||
* If this pointer in <code>NULL</code> the script runs will be determined using the
|
||||
* Unicode code points.
|
||||
*
|
||||
* @param localeRuns is a pointer to a <code>pl_localeRuns</code> object representing locale runs.
|
||||
* The <code>Locale</code> objects are used to determind the language of the text. If this
|
||||
* pointer is <code>NULL</code> the default locale will be used for all of the text.
|
||||
*
|
||||
* @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
|
||||
*
|
||||
* @param vertical is <code>TRUE</code> if the paragraph should be set vertically.
|
||||
*
|
||||
* @param status will be set to any error code encountered during construction.
|
||||
*
|
||||
* @return a pointer to the newly created <code>pl_paragraph</code> object. The object
|
||||
* will remain valid until <code>pl_close</code> is called.
|
||||
*
|
||||
* @see ubidi.h
|
||||
* @see longine.h
|
||||
* @see plruns.h
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_paragraph * U_EXPORT2
|
||||
pl_create(const LEUnicode chars[],
|
||||
le_int32 count,
|
||||
const pl_fontRuns *fontRuns,
|
||||
const pl_valueRuns *levelRuns,
|
||||
const pl_valueRuns *scriptRuns,
|
||||
const pl_localeRuns *localeRuns,
|
||||
UBiDiLevel paragraphLevel,
|
||||
le_bool vertical,
|
||||
LEErrorCode *status);
|
||||
|
||||
/**
|
||||
* Close the given paragraph layout object.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code> object to be
|
||||
* closed. Once this routine returns the object
|
||||
* can no longer be referenced
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_close(pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Examine the given text and determine if it contains characters in any
|
||||
* script which requires complex processing to be rendered correctly.
|
||||
*
|
||||
* @param chars is an array of the characters in the paragraph
|
||||
*
|
||||
* @param count is the number of characters in the paragraph.
|
||||
*
|
||||
* @return <code>TRUE</code> if any of the text requires complex processing.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
|
||||
U_DRAFT le_bool U_EXPORT2
|
||||
pl_isComplex(const LEUnicode chars[],
|
||||
le_int32 count);
|
||||
|
||||
/**
|
||||
* Return the resolved paragraph level. This is useful for those cases
|
||||
* where the bidi analysis has determined the level based on the first
|
||||
* strong character in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @return the resolved paragraph level.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT UBiDiLevel U_EXPORT2
|
||||
pl_getParagraphLevel(pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Return the directionality of the text in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @return <code>UBIDI_LTR</code> if the text is all left to right,
|
||||
* <code>UBIDI_RTL</code> if the text is all right to left,
|
||||
* or <code>UBIDI_MIXED</code> if the text has mixed direction.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT UBiDiDirection U_EXPORT2
|
||||
pl_getTextDirection(pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Get the max ascent value for all the fonts
|
||||
* in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* Return the max ascent value for all the fonts
|
||||
* in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @return the ascent value.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getAscent(const pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Return the max descent value for all the fonts
|
||||
* in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @return the decent value.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getDescent(const pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Return the max leading value for all the fonts
|
||||
* in the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @return the leading value.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLeading(const pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Reset line breaking to start from the beginning of the paragraph.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_reflow(pl_paragraph *paragraph);
|
||||
|
||||
/**
|
||||
* Return a <code>pl_line</code> object which represents next line
|
||||
* in the paragraph. The width of the line is specified each time so that it can
|
||||
* be varied to support arbitrary paragraph shapes.
|
||||
*
|
||||
* @param paragraph the <code>pl_paragraph</code>
|
||||
* @param width is the width of the line. If <code>width</code> is less than or equal
|
||||
* to zero, a <code>ParagraphLayout::Line</code> object representing the
|
||||
* rest of the paragraph will be returned.
|
||||
*
|
||||
* @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
|
||||
* is responsible for deleting the object. Returns <code>NULL</code> if there are no
|
||||
* more lines in the paragraph.
|
||||
*
|
||||
* @see pl_line
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_line * U_EXPORT2
|
||||
pl_nextLine(pl_paragraph *paragraph, float width);
|
||||
|
||||
/**
|
||||
* Close the given line object. Line objects are created
|
||||
* by <code>pl_nextLine</code> but it is the client's responsibility
|
||||
* to close them by calling this routine.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object to close.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_closeLine(pl_line *line);
|
||||
|
||||
/**
|
||||
* Count the number of visual runs in the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
*
|
||||
* @return the number of visual runs.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_countLineRuns(const pl_line *line);
|
||||
|
||||
/**
|
||||
* Get the ascent of the line. This is the maximum ascent
|
||||
* of all the fonts on the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
*
|
||||
* @return the ascent of the line.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLineAscent(const pl_line *line);
|
||||
|
||||
/**
|
||||
* Get the descent of the line. This is the maximum descent
|
||||
* of all the fonts on the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
*
|
||||
* @return the descent of the line.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLineDescent(const pl_line *line);
|
||||
|
||||
/**
|
||||
* Get the leading of the line. This is the maximum leading
|
||||
* of all the fonts on the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
*
|
||||
* @return the leading of the line.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLineLeading(const pl_line *line);
|
||||
|
||||
/**
|
||||
* Get the width of the line. This is a convenience method
|
||||
* which returns the last X position of the last visual run
|
||||
* in the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
*
|
||||
* @return the width of the line.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLineWidth(const pl_line *line);
|
||||
|
||||
/**
|
||||
* Get a <code>ParagraphLayout::VisualRun</code> object for a given
|
||||
* visual run in the line.
|
||||
*
|
||||
* @param line the <code>pl_line</code> object.
|
||||
* @param runIndex is the index of the run, in visual order.
|
||||
*
|
||||
* @return the <code>pl_visualRun</code> object representing the
|
||||
* visual run. This object is owned by the <code>pl_line</code> object which
|
||||
* created it, and will remain valid for as long as the <code>pl_line</code>
|
||||
* object is valid.
|
||||
*
|
||||
* @see pl_visualRun
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const pl_visualRun * U_EXPORT2
|
||||
pl_getLineVisualRun(const pl_line *line, le_int32 runIndex);
|
||||
|
||||
/**
|
||||
* Get the <code>le_font</code> object which
|
||||
* represents the font of the visual run. This will always
|
||||
* be a non-composite font.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the <code>le_font</code> object which represents the
|
||||
* font of the visual run.
|
||||
*
|
||||
* @see le_font
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const le_font * U_EXPORT2
|
||||
pl_getVisualRunFont(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* Get the direction of the visual run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the direction of the run. This will be <code>UBIDI_LTR</code> if the
|
||||
* run is left-to-right and <code>UBIDI_RTL</code> if the line is right-to-left.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT UBiDiDirection U_EXPORT2
|
||||
pl_getVisualRunDirection(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* Get the number of glyphs in the visual run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the number of glyphs.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getVisualRunGlyphCount(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and
|
||||
* <code>0xFFFF</code> should be ignored.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the address of the array of glyphs for this visual run. The storage
|
||||
* is owned by the <code>pl_visualRun</code> object and must not be deleted.
|
||||
* It will remain valid as long as the <code>pl_visualRun</code> object is valid.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const LEGlyphID * U_EXPORT2
|
||||
pl_getVisualRunGlyphs(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* Get the (x, y) positions of the glyphs in the visual run. To simplify storage
|
||||
* management, the x and y positions are stored in a single array with the x positions
|
||||
* at even offsets in the array and the corresponding y position in the following odd offset.
|
||||
* There is an extra (x, y) pair at the end of the array which represents the advance of
|
||||
* the final glyph in the run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the address of the array of glyph positions for this visual run. The storage
|
||||
* is owned by the <code>pl_visualRun</code> object and must not be deleted.
|
||||
* It will remain valid as long as the <code>pl_visualRun</code> object is valid.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const float * U_EXPORT2
|
||||
pl_getVisualRunPositions(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* Get the glyph-to-character map for this visual run. This maps the indices into
|
||||
* the glyph array to indices into the character array used to create the paragraph.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the address of the character-to-glyph map for this visual run. The storage
|
||||
* is owned by the <code>pl_visualRun</code> object and must not be deleted.
|
||||
* It will remain valid as long as the <code>pl_visualRun</code> object is valid.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const le_int32 * U_EXPORT2
|
||||
pl_getVisualRunGlyphToCharMap(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* A convenience method which returns the ascent value for the font
|
||||
* associated with this run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the ascent value of this run's font.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getVisualRunAscent(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* A convenience method which returns the descent value for the font
|
||||
* associated with this run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the descent value of this run's font.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getVisualRunDescent(const pl_visualRun *run);
|
||||
|
||||
/**
|
||||
* A convenience method which returns the leading value for the font
|
||||
* associated with this run.
|
||||
*
|
||||
* @param run the <code>pl_visualRun</code> object.
|
||||
*
|
||||
* @return the leading value of this run's font.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getVisualRunLeading(const pl_visualRun *run);
|
||||
|
||||
#endif
|
429
icu4c/source/layoutex/layout/plruns.h
Normal file
429
icu4c/source/layoutex/layout/plruns.h
Normal file
@ -0,0 +1,429 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PLRUNS_H
|
||||
#define __PLRUNS_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ubidi.h"
|
||||
#include "layout/LETypes.h"
|
||||
|
||||
#include "layout/loengine.h"
|
||||
|
||||
typedef void pl_fontRuns;
|
||||
typedef void pl_valueRuns;
|
||||
typedef void pl_localeRuns;
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C API for run arrays.
|
||||
* \internal
|
||||
*
|
||||
* This is a technology preview. The API may
|
||||
* change significantly.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct a <code>pl_fontRuns</code> object from pre-existing arrays of fonts
|
||||
* and limit indices.
|
||||
*
|
||||
* @param fonts is the address of an array of pointers to <code>le_font</code> objects. This
|
||||
* array, and the <code>le_font</code> objects to which it points must remain
|
||||
* valid until the <code>pl_fontRuns</code> object is closed.
|
||||
*
|
||||
* @param limits is the address of an array of limit indices. This array must remain valid until
|
||||
* the <code>pl_fontRuns</code> object is closed.
|
||||
*
|
||||
* @param count is the number of entries in the two arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_fontRuns * U_EXPORT2
|
||||
pl_openFontRuns(const le_font **fonts,
|
||||
const le_int32 *limits,
|
||||
le_int32 count);
|
||||
|
||||
/**
|
||||
* Construct an empty <code>pl_fontRuns</code> object. Clients can add font and limit
|
||||
* indices arrays using the <code>pl_addFontRun</code> routine.
|
||||
*
|
||||
* @param initialCapacity is the initial size of the font and limit indices arrays. If
|
||||
* this value is zero, no arrays will be allocated.
|
||||
*
|
||||
* @see pl_addFontRun
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_fontRuns * U_EXPORT2
|
||||
pl_openEmptyFontRuns(le_int32 initialCapacity);
|
||||
|
||||
/**
|
||||
* Close the given <code>pl_fontRuns</code> object. Once this
|
||||
* call returns, the object can no longer be referenced.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_closeFontRuns(pl_fontRuns *fontRuns);
|
||||
|
||||
/**
|
||||
* Get the number of font runs.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* @return the number of entries in the limit indices array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getFontRunCount(const pl_fontRuns *fontRuns);
|
||||
|
||||
/**
|
||||
* Reset the number of font runs to zero.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_resetFontRuns(pl_fontRuns *fontRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for the last font run. This is the
|
||||
* number of characters in the text.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* @return the last limit index.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getFontRunLastLimit(const pl_fontRuns *fontRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for a particular font run.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
* @param run is the run. This is an index into the limit index array.
|
||||
*
|
||||
* @return the limit index for the run, or -1 if <code>run</code> is out of bounds.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getFontRunLimit(const pl_fontRuns *fontRuns,
|
||||
le_int32 run);
|
||||
|
||||
/**
|
||||
* Get the <code>le_font</code> object assoicated with the given run
|
||||
* of text. Use <code>pl_getFontRunLimit(run)</code> to get the corresponding
|
||||
* limit index.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
* @param run is the index into the font and limit indices arrays.
|
||||
*
|
||||
* @return the <code>le_font</code> associated with the given text run.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const le_font * U_EXPORT2
|
||||
pl_getFontRunFont(const pl_fontRuns *fontRuns,
|
||||
le_int32 run);
|
||||
|
||||
|
||||
/**
|
||||
* Add a new font run to the given <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* If the <code>pl_fontRuns</code> object was not created by calling
|
||||
* <code>pl_openEmptyFontRuns</code>, this method will return a run index of -1.
|
||||
*
|
||||
* @param fontRuns is the <code>pl_fontRuns</code> object.
|
||||
*
|
||||
* @param font is the address of the <code>le_font</code> to add. This object must
|
||||
* remain valid until the <code>pl_fontRuns</code> object is closed.
|
||||
*
|
||||
* @param limit is the limit index to add
|
||||
*
|
||||
* @return the run index where the font and limit index were stored, or -1 if
|
||||
* the run cannot be added.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_addFontRun(pl_fontRuns *fontRuns,
|
||||
const le_font *font,
|
||||
le_int32 limit);
|
||||
|
||||
/**
|
||||
* Construct a <code>pl_valueRuns</code> object from pre-existing arrays of values
|
||||
* and limit indices.
|
||||
*
|
||||
* @param values is the address of an array of values. This array must remain valid until
|
||||
the <code>pl_valueRuns</code> object is closed.
|
||||
*
|
||||
* @param limits is the address of an array of limit indices. This array must remain valid until
|
||||
* the <code>pl_valueRuns</code> object is closed.
|
||||
*
|
||||
* @param count is the number of entries in the two arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_valueRuns * U_EXPORT2
|
||||
pl_openValueRuns(const le_int32 *values,
|
||||
const le_int32 *limits,
|
||||
le_int32 count);
|
||||
|
||||
/**
|
||||
* Construct an empty <code>pl_valueRuns</code> object. Clients can add values and limits
|
||||
* using the <code>pl_addValueRun</code> routine.
|
||||
*
|
||||
* @param initialCapacity is the initial size of the value and limit indices arrays. If
|
||||
* this value is zero, no arrays will be allocated.
|
||||
*
|
||||
* @see pl_addValueRun
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_valueRuns * U_EXPORT2
|
||||
pl_openEmptyValueRuns(le_int32 initialCapacity);
|
||||
|
||||
/**
|
||||
* Close the given <code>pl_valueRuns</code> object. Once this
|
||||
* call returns, the object can no longer be referenced.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_closeValueRuns(pl_valueRuns *valueRuns);
|
||||
|
||||
/**
|
||||
* Get the number of value runs.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* @return the number of value runs.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getValueRunCount(const pl_valueRuns *valueRuns);
|
||||
|
||||
/**
|
||||
* Reset the number of value runs to zero.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_resetValueRuns(pl_valueRuns *valueRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for the last value run. This is the
|
||||
* number of characters in the text.
|
||||
*
|
||||
* @param valuetRuns is the <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* @return the last limit index.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getValueRunLastLimit(const pl_valueRuns *valueRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for a particular value run.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
* @param run is the run index.
|
||||
*
|
||||
* @return the limit index for the run, or -1 if <code>run</code> is out of bounds.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getValueRunLimit(const pl_valueRuns *valueRuns,
|
||||
le_int32 run);
|
||||
|
||||
/**
|
||||
* Get the value assoicated with the given run * of text. Use
|
||||
* <code>pl_getValueRunLimit(run)</code> to get the corresponding
|
||||
* limit index.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
* @param run is the run index.
|
||||
*
|
||||
* @return the value associated with the given text run.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getValueRunValue(const pl_valueRuns *valueRuns,
|
||||
le_int32 run);
|
||||
|
||||
|
||||
/**
|
||||
* Add a new font run to the given <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* If the <code>pl_valueRuns</code> object was not created by calling
|
||||
* <code>pl_openEmptyFontRuns</code>, this method will return a run index of -1.
|
||||
*
|
||||
* @param valueRuns is the <code>pl_valueRuns</code> object.
|
||||
*
|
||||
* @param value is the value to add.
|
||||
*
|
||||
* @param limit is the limit index to add
|
||||
*
|
||||
* @return the run index where the font and limit index were stored, or -1 if
|
||||
* the run cannot be added.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_addValueRun(pl_valueRuns *valueRuns,
|
||||
le_int32 value,
|
||||
le_int32 limit);
|
||||
|
||||
/**
|
||||
* Construct a <code>pl_localeRuns</code> object from pre-existing arrays of fonts
|
||||
* and limit indices.
|
||||
*
|
||||
* @param locales is the address of an array of pointers to locale name strings. This
|
||||
* array must remain valid until the <code>pl_localeRuns</code> object is destroyed.
|
||||
*
|
||||
* @param limits is the address of an array of limit indices. This array must remain valid until
|
||||
* the <code>pl_valueRuns</code> object is destroyed.
|
||||
*
|
||||
* @param count is the number of entries in the two arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_localeRuns * U_EXPORT2
|
||||
pl_openLocaleRuns(const char **locales,
|
||||
const le_int32 *limits,
|
||||
le_int32 count);
|
||||
|
||||
/**
|
||||
* Construct an empty <code>pl_localeRuns</code> object. Clients can add font and limit
|
||||
* indices arrays using the <code>pl_addFontRun</code> routine.
|
||||
*
|
||||
* @param initialCapacity is the initial size of the font and limit indices arrays. If
|
||||
* this value is zero, no arrays will be allocated.
|
||||
*
|
||||
* @see pl_addLocaleRun
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT pl_localeRuns * U_EXPORT2
|
||||
pl_openEmptyLocaleRuns(le_int32 initialCapacity);
|
||||
|
||||
/**
|
||||
* Close the given <code>pl_localeRuns</code> object. Once this
|
||||
* call returns, the object can no longer be referenced.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_closeLocaleRuns(pl_localeRuns *localeRuns);
|
||||
|
||||
/**
|
||||
* Get the number of font runs.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* @return the number of entries in the limit indices array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLocaleRunCount(const pl_localeRuns *localeRuns);
|
||||
|
||||
/**
|
||||
* Reset the number of locale runs to zero.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
pl_resetLocaleRuns(pl_localeRuns *localeRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for the last font run. This is the
|
||||
* number of characters in the text.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* @return the last limit index.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns);
|
||||
|
||||
/**
|
||||
* Get the limit index for a particular font run.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
* @param run is the run. This is an index into the limit index array.
|
||||
*
|
||||
* @return the limit index for the run, or -1 if <code>run</code> is out of bounds.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
|
||||
le_int32 run);
|
||||
|
||||
/**
|
||||
* Get the <code>le_font</code> object assoicated with the given run
|
||||
* of text. Use <code>pl_getLocaleRunLimit(run)</code> to get the corresponding
|
||||
* limit index.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
* @param run is the index into the font and limit indices arrays.
|
||||
*
|
||||
* @return the <code>le_font</code> associated with the given text run.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT const char * U_EXPORT2
|
||||
pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
|
||||
le_int32 run);
|
||||
|
||||
|
||||
/**
|
||||
* Add a new run to the given <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* If the <code>pl_localeRuns</code> object was not created by calling
|
||||
* <code>pl_openEmptyLocaleRuns</code>, this method will return a run index of -1.
|
||||
*
|
||||
* @param localeRuns is the <code>pl_localeRuns</code> object.
|
||||
*
|
||||
* @param locale is the name of the locale to add. This name must
|
||||
* remain valid until the <code>pl_localeRuns</code> object is closed.
|
||||
*
|
||||
* @param limit is the limit index to add
|
||||
*
|
||||
* @return the run index where the font and limit index were stored, or -1 if
|
||||
* the run cannot be added.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
U_DRAFT le_int32 U_EXPORT2
|
||||
pl_addLocaleRun(pl_localeRuns *localeRuns,
|
||||
const char *locale,
|
||||
le_int32 limit);
|
||||
|
||||
#endif
|
@ -4,6 +4,7 @@
|
||||
Version="8.00"
|
||||
Name="layoutex"
|
||||
ProjectGUID="{37FC2C7F-1904-4811-8955-2F478830EAD1}"
|
||||
RootNamespace="layoutex"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
@ -219,6 +220,14 @@
|
||||
RelativePath=".\ParagraphLayout.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\playout.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\plruns.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RunArrays.cpp"
|
||||
>
|
||||
@ -254,6 +263,32 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\playout.h"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\plruns.h"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\RunArrays.h"
|
||||
>
|
||||
|
323
icu4c/source/layoutex/playout.cpp
Normal file
323
icu4c/source/layoutex/playout.cpp
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/loengine.h"
|
||||
#include "layout/plruns.h"
|
||||
#include "layout/playout.h"
|
||||
|
||||
#include "unicode/locid.h"
|
||||
|
||||
#include "layout/LayoutEngine.h"
|
||||
#include "layout/ParagraphLayout.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
U_CAPI pl_paragraph * U_EXPORT2
|
||||
pl_create(const LEUnicode chars[],
|
||||
le_int32 count,
|
||||
const pl_fontRuns *fontRuns,
|
||||
const pl_valueRuns *levelRuns,
|
||||
const pl_valueRuns *scriptRuns,
|
||||
const pl_localeRuns *localeRuns,
|
||||
UBiDiLevel paragraphLevel,
|
||||
le_bool vertical,
|
||||
LEErrorCode *status)
|
||||
{
|
||||
ParagraphLayout *pl = new ParagraphLayout(chars, count, (const FontRuns *) fontRuns,
|
||||
(const ValueRuns *) levelRuns, (const ValueRuns *) scriptRuns, (const LocaleRuns *) localeRuns,
|
||||
paragraphLevel, vertical, *status);
|
||||
|
||||
return (pl_paragraph *) pl;
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_close(pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
delete pl;
|
||||
}
|
||||
|
||||
U_CAPI le_bool U_EXPORT2
|
||||
pl_isComplex(const LEUnicode chars[],
|
||||
le_int32 count)
|
||||
{
|
||||
return ParagraphLayout::isComplex(chars, count);
|
||||
}
|
||||
|
||||
U_CAPI UBiDiLevel U_EXPORT2
|
||||
pl_getParagraphLevel(pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pl->getParagraphLevel();
|
||||
}
|
||||
|
||||
U_CAPI UBiDiDirection U_EXPORT2
|
||||
pl_getTextDirection(pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return UBIDI_LTR;
|
||||
}
|
||||
|
||||
return pl->getTextDirection();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getAscent(const pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pl->getAscent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getDescent(const pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pl->getDescent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLeading(const pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pl->getLeading();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_reflow(pl_paragraph *paragraph)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
return pl->reflow();
|
||||
}
|
||||
|
||||
U_CAPI pl_line * U_EXPORT2
|
||||
pl_nextLine(pl_paragraph *paragraph, float width)
|
||||
{
|
||||
ParagraphLayout *pl = (ParagraphLayout *) paragraph;
|
||||
|
||||
if (pl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (pl_line *) pl->nextLine(width);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_closeLine(pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
delete ll;
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_countLineRuns(const pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ll->countRuns();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLineAscent(const pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ll->getAscent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLineDescent(const pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ll->getDescent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLineLeading(const pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ll->getLeading();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLineWidth(const pl_line *line)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ll->getWidth();
|
||||
}
|
||||
|
||||
U_CAPI const pl_visualRun * U_EXPORT2
|
||||
pl_getLineVisualRun(const pl_line *line, le_int32 runIndex)
|
||||
{
|
||||
ParagraphLayout::Line *ll = (ParagraphLayout::Line *) line;
|
||||
|
||||
if (ll == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (pl_visualRun *) ll->getVisualRun(runIndex);
|
||||
}
|
||||
|
||||
U_CAPI const le_font * U_EXPORT2
|
||||
pl_getVisualRunFont(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (const le_font *) vr->getFont();
|
||||
}
|
||||
|
||||
U_CAPI UBiDiDirection U_EXPORT2
|
||||
pl_getVisualRunDirection(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return UBIDI_LTR;
|
||||
}
|
||||
|
||||
return vr->getDirection();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getVisualRunGlyphCount(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->getGlyphCount();
|
||||
}
|
||||
|
||||
U_CAPI const LEGlyphID * U_EXPORT2
|
||||
pl_getVisualRunGlyphs(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vr->getGlyphs();
|
||||
}
|
||||
|
||||
U_CAPI const float * U_EXPORT2
|
||||
pl_getVisualRunPositions(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vr->getPositions();
|
||||
}
|
||||
|
||||
U_CAPI const le_int32 * U_EXPORT2
|
||||
pl_getVisualRunGlyphToCharMap(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vr->getGlyphToCharMap();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getVisualRunAscent(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vr->getAscent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getVisualRunDescent(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vr->getDescent();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getVisualRunLeading(const pl_visualRun *run)
|
||||
{
|
||||
ParagraphLayout::VisualRun *vr = (ParagraphLayout::VisualRun *) run;
|
||||
|
||||
if (vr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vr->getLeading();
|
||||
}
|
||||
|
508
icu4c/source/layoutex/plruns.cpp
Normal file
508
icu4c/source/layoutex/plruns.cpp
Normal file
@ -0,0 +1,508 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/loengine.h"
|
||||
#include "layout/plruns.h"
|
||||
|
||||
#include "unicode/locid.h"
|
||||
|
||||
#include "layout/LayoutEngine.h"
|
||||
#include "layout/RunArrays.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
U_CAPI pl_fontRuns * U_EXPORT2
|
||||
pl_openFontRuns(const le_font **fonts,
|
||||
const le_int32 *limits,
|
||||
le_int32 count)
|
||||
{
|
||||
return (pl_fontRuns *) new FontRuns((const LEFontInstance **) fonts, limits, count);
|
||||
}
|
||||
|
||||
U_CAPI pl_fontRuns * U_EXPORT2
|
||||
pl_openEmptyFontRuns(le_int32 initialCapacity)
|
||||
{
|
||||
return (pl_fontRuns *) new FontRuns(initialCapacity);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_closeFontRuns(pl_fontRuns *fontRuns)
|
||||
{
|
||||
FontRuns *fr = (FontRuns *) fontRuns;
|
||||
|
||||
delete fr;
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getFontRunCount(const pl_fontRuns *fontRuns)
|
||||
{
|
||||
const FontRuns *fr = (const FontRuns *) fontRuns;
|
||||
|
||||
if (fr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fr->getCount();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_resetFontRuns(pl_fontRuns *fontRuns)
|
||||
{
|
||||
FontRuns *fr = (FontRuns *) fontRuns;
|
||||
|
||||
if (fr != NULL) {
|
||||
fr->reset();
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getFontRunLastLimit(const pl_fontRuns *fontRuns)
|
||||
{
|
||||
const FontRuns *fr = (const FontRuns *) fontRuns;
|
||||
|
||||
if (fr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fr->getLimit();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getFontRunLimit(const pl_fontRuns *fontRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const FontRuns *fr = (const FontRuns *) fontRuns;
|
||||
|
||||
if (fr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fr->getLimit(run);
|
||||
}
|
||||
|
||||
U_CAPI const le_font * U_EXPORT2
|
||||
pl_getFontRunFont(const pl_fontRuns *fontRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const FontRuns *fr = (const FontRuns *) fontRuns;
|
||||
|
||||
if (fr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (const le_font *) fr->getFont(run);
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_addFontRun(pl_fontRuns *fontRuns,
|
||||
const le_font *font,
|
||||
le_int32 limit)
|
||||
{
|
||||
FontRuns *fr = (FontRuns *) fontRuns;
|
||||
|
||||
if (fr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fr->add((const LEFontInstance *) font, limit);
|
||||
}
|
||||
|
||||
U_CAPI pl_valueRuns * U_EXPORT2
|
||||
pl_openValueRuns(const le_int32 *values,
|
||||
const le_int32 *limits,
|
||||
le_int32 count)
|
||||
{
|
||||
return (pl_valueRuns *) new ValueRuns(values, limits, count);
|
||||
}
|
||||
|
||||
U_CAPI pl_valueRuns * U_EXPORT2
|
||||
pl_openEmptyValueRuns(le_int32 initialCapacity)
|
||||
{
|
||||
return (pl_valueRuns *) new ValueRuns(initialCapacity);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_closeValueRuns(pl_valueRuns *valueRuns)
|
||||
{
|
||||
ValueRuns *vr = (ValueRuns *) valueRuns;
|
||||
|
||||
delete vr;
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getValueRunCount(const pl_valueRuns *valueRuns)
|
||||
{
|
||||
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->getCount();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_resetValueRuns(pl_valueRuns *valueRuns)
|
||||
{
|
||||
ValueRuns *vr = (ValueRuns *) valueRuns;
|
||||
|
||||
if (vr != NULL) {
|
||||
vr->reset();
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getValueRunLastLimit(const pl_valueRuns *valueRuns)
|
||||
{
|
||||
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->getLimit();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getValueRunLimit(const pl_valueRuns *valueRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->getLimit(run);
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getValueRunValue(const pl_valueRuns *valueRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->getValue(run);
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_addValueRun(pl_valueRuns *valueRuns,
|
||||
le_int32 value,
|
||||
le_int32 limit)
|
||||
{
|
||||
ValueRuns *vr = (ValueRuns *) valueRuns;
|
||||
|
||||
if (vr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vr->add(value, limit);
|
||||
}
|
||||
|
||||
class ULocRuns : public LocaleRuns
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
|
||||
* and limit indices.
|
||||
*
|
||||
* @param locales is the address of an array of locale name strings. This array,
|
||||
* and the <code>Locale</code> objects to which it points, must remain valid until
|
||||
* the <code>LocaleRuns</code> object is destroyed.
|
||||
*
|
||||
* @param limits is the address of an array of limit indices. This array must remain valid until the
|
||||
* <code>LocaleRuns</code> object is destroyed.
|
||||
*
|
||||
* @param count is the number of entries in the two arrays.
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
ULocRuns(const char **locales, const le_int32 *limits, le_int32 count);
|
||||
|
||||
/**
|
||||
* Construct an empty <code>LoIDRuns</code> object. Clients can add locale and limit
|
||||
* indices arrays using the <code>add</code> method.
|
||||
*
|
||||
* @param initialCapacity is the initial size of the locale and limit indices arrays. If
|
||||
* this value is zero, no arrays will be allocated.
|
||||
*
|
||||
* @see add
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
ULocRuns(le_int32 initialCapacity);
|
||||
|
||||
/**
|
||||
* The destructor; virtual so that subclass destructors are invoked as well.
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
virtual ~ULocRuns();
|
||||
|
||||
/**
|
||||
* Get the name of the locale assoicated with the given run
|
||||
* of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
|
||||
* limit index.
|
||||
*
|
||||
* @param run is the index into the font and limit indices arrays.
|
||||
*
|
||||
* @return the locale name associated with the given text run.
|
||||
*
|
||||
* @see RunArray::getLimit
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
const char *getLocaleName(le_int32 run) const;
|
||||
|
||||
/**
|
||||
* Add a <code>Locale</code> and limit index pair to the data arrays and return
|
||||
* the run index where the data was stored. This method calls
|
||||
* <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
|
||||
*
|
||||
* If the <code>ULocRuns</code> object was created with a client-supplied
|
||||
* locale and limit indices arrays, this method will return a run index of -1.
|
||||
*
|
||||
* Subclasses should not override this method. Rather they should provide a new <code>add</code>
|
||||
* method which takes a locale name and a limit index along with whatever other data they implement.
|
||||
* The new <code>add</code> method should first call this method to grow the font and limit indices
|
||||
* arrays, and use the returned run index to store data their own arrays.
|
||||
*
|
||||
* @param locale is the name of the locale to add. This object must remain valid
|
||||
* until the <code>ULocRuns</code> object is destroyed.
|
||||
*
|
||||
* @param limit is the limit index to add
|
||||
*
|
||||
* @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
le_int32 add(const char *locale, le_int32 limit);
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
|
||||
|
||||
protected:
|
||||
virtual void init(le_int32 capacity);
|
||||
virtual void grow(le_int32 capacity);
|
||||
|
||||
private:
|
||||
|
||||
inline ULocRuns();
|
||||
inline ULocRuns(const ULocRuns &other);
|
||||
inline ULocRuns &operator=(const ULocRuns & /*other*/) { return *this; };
|
||||
|
||||
/**
|
||||
* The address of this static class variable serves as this class's ID
|
||||
* for ICU "poor man's RTTI".
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
const char **fLocaleNames;
|
||||
Locale **fLocalesCopy;
|
||||
};
|
||||
|
||||
const char ULocRuns::fgClassID = 0;
|
||||
|
||||
inline ULocRuns::ULocRuns()
|
||||
: LocaleRuns(0), fLocaleNames(NULL)
|
||||
{
|
||||
// nothing else to do...
|
||||
}
|
||||
|
||||
inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
|
||||
: LocaleRuns(0), fLocaleNames(NULL)
|
||||
{
|
||||
// nothing else to do...
|
||||
}
|
||||
|
||||
const Locale **getLocales(const char **localeNames, le_int32 count)
|
||||
{
|
||||
Locale **locales = LE_NEW_ARRAY(Locale *, count);
|
||||
|
||||
for (int i = 0; i < count; i += 1) {
|
||||
locales[i] = new Locale(Locale::createFromName(localeNames[i]));
|
||||
}
|
||||
|
||||
return (const Locale **) locales;
|
||||
}
|
||||
|
||||
ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
|
||||
: LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
|
||||
{
|
||||
// nothing else to do...
|
||||
}
|
||||
|
||||
ULocRuns::ULocRuns(le_int32 initialCapacity)
|
||||
: LocaleRuns(initialCapacity), fLocaleNames(NULL)
|
||||
{
|
||||
if(initialCapacity > 0) {
|
||||
fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
ULocRuns::~ULocRuns()
|
||||
{
|
||||
le_int32 count = getCount();
|
||||
|
||||
for(int i = 0; i < count; i += 1) {
|
||||
delete fLocales[i];
|
||||
}
|
||||
|
||||
if (fClientArrays) {
|
||||
LE_DELETE_ARRAY(fLocales);
|
||||
fLocales = NULL;
|
||||
} else {
|
||||
LE_DELETE_ARRAY(fLocaleNames);
|
||||
fLocaleNames = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ULocRuns::init(le_int32 capacity)
|
||||
{
|
||||
LocaleRuns::init(capacity);
|
||||
fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
|
||||
}
|
||||
|
||||
void ULocRuns::grow(le_int32 capacity)
|
||||
{
|
||||
RunArray::grow(capacity);
|
||||
fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity);
|
||||
}
|
||||
|
||||
le_int32 ULocRuns::add(const char *locale, le_int32 limit)
|
||||
{
|
||||
Locale *loc = new Locale(Locale::createFromName(locale));
|
||||
le_int32 index = LocaleRuns::add(loc, limit);
|
||||
|
||||
if (index >= 0) {
|
||||
char **localeNames = (char **) fLocaleNames;
|
||||
|
||||
localeNames[index] = (char *) locale;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
const char *ULocRuns::getLocaleName(le_int32 run) const
|
||||
{
|
||||
if (run < 0 || run >= getCount()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fLocaleNames[run];
|
||||
}
|
||||
|
||||
U_CAPI pl_localeRuns * U_EXPORT2
|
||||
pl_openLocaleRuns(const char **locales,
|
||||
const le_int32 *limits,
|
||||
le_int32 count)
|
||||
{
|
||||
return (pl_localeRuns *) new ULocRuns(locales, limits, count);
|
||||
}
|
||||
|
||||
U_CAPI pl_localeRuns * U_EXPORT2
|
||||
pl_openEmptyLocaleRuns(le_int32 initialCapacity)
|
||||
{
|
||||
return (pl_localeRuns *) new ULocRuns(initialCapacity);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_closeLocaleRuns(pl_localeRuns *localeRuns)
|
||||
{
|
||||
ULocRuns *lr = (ULocRuns *) localeRuns;
|
||||
|
||||
delete lr;
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
|
||||
{
|
||||
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
||||
|
||||
if (lr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lr->getCount();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
pl_resetLocaleRuns(pl_localeRuns *localeRuns)
|
||||
{
|
||||
ULocRuns *lr = (ULocRuns *) localeRuns;
|
||||
|
||||
if (lr != NULL) {
|
||||
lr->reset();
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
|
||||
{
|
||||
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
||||
|
||||
if (lr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lr->getLimit();
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
||||
|
||||
if (lr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lr->getLimit(run);
|
||||
}
|
||||
|
||||
U_CAPI const char * U_EXPORT2
|
||||
pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
|
||||
le_int32 run)
|
||||
{
|
||||
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
||||
|
||||
if (lr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return lr->getLocaleName(run);
|
||||
}
|
||||
|
||||
U_CAPI le_int32 U_EXPORT2
|
||||
pl_addLocaleRun(pl_localeRuns *localeRuns,
|
||||
const char *locale,
|
||||
le_int32 limit)
|
||||
{
|
||||
ULocRuns *lr = (ULocRuns *) localeRuns;
|
||||
|
||||
if (lr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lr->add(locale, limit);
|
||||
}
|
@ -166,14 +166,12 @@ le_bool GnomeFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FT_OutlineGlyph oglyph = (FT_OutlineGlyph) fFace->glyph;
|
||||
|
||||
if (pointNumber >= oglyph->outline.n_points) {
|
||||
if (pointNumber >= fFace->glyph->outline.n_points) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
point.fX = oglyph->outline.points[pointNumber].x >> 6;
|
||||
point.fY = oglyph->outline.points[pointNumber].y >> 6;
|
||||
point.fX = fFace->glyph->outline.points[pointNumber].x >> 6;
|
||||
point.fY = fFace->glyph->outline.points[pointNumber].y >> 6;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
## Makefile.in for ICU - samples/layout
|
||||
## Copyright (c) 2001-2003, International Business Machines Corporation and
|
||||
## Copyright (c) 2001-2007, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
|
||||
## Source directory information
|
||||
@ -20,13 +20,18 @@ subdir = samples/layout
|
||||
CLEANFILES = *~ $(DEPS)
|
||||
|
||||
## Target information
|
||||
TARGET = gnomelayout
|
||||
TARGET = gnomelayout
|
||||
CTARGET = cgnomelayout
|
||||
|
||||
CPPFLAGS += -DLE_USE_CMEMORY `pkg-config --cflags libgnomeui-2.0 freetype2 cairo` -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/layoutex -I$(top_srcdir)/layout -I$(top_srcdir) -g
|
||||
|
||||
LIBS = $(LIBICULX) $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) @LIBS@ @LIB_M@ `pkg-config --libs libgnomeui-2.0 freetype2 cairo`
|
||||
|
||||
OBJECTS=cmaps.o UnicodeReader.o GnomeGUISupport.o FontMap.o GnomeFontMap.o ScriptCompositeFontInstance.o GnomeFontInstance.o FontTableCache.o paragraph.o gnomelayout.o
|
||||
COMMON=cmaps.o UnicodeReader.o GnomeGUISupport.o FontMap.o GnomeFontMap.o ScriptCompositeFontInstance.o GnomeFontInstance.o FontTableCache.o paragraph.o
|
||||
|
||||
OBJECTS=gnomelayout.o
|
||||
|
||||
COBJECTS=gnomeglue.o pflow.o rsurface.o ucreader.o cgnomelayout.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
@ -44,16 +49,20 @@ clean: clean-local
|
||||
distclean : distclean-local
|
||||
dist: dist-local
|
||||
check: all check-local
|
||||
c-all: c-all-local
|
||||
c-check: c-all c-check-local
|
||||
|
||||
all-local: $(TARGET)
|
||||
|
||||
c-all-local: $(CTARGET)
|
||||
|
||||
install-local:
|
||||
|
||||
dist-local:
|
||||
|
||||
clean-local:
|
||||
test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
|
||||
$(RMV) $(OBJECTS) $(TARGET)
|
||||
$(RMV) $(COMMON) $(OBJECTS) $(COBJECTS) $(TARGET)
|
||||
|
||||
distclean-local: clean-local
|
||||
$(RMV) Makefile
|
||||
@ -61,6 +70,9 @@ distclean-local: clean-local
|
||||
check-local: all-local
|
||||
$(INVOKE) ./$(TARGET)
|
||||
|
||||
c-check-local: c-all-local
|
||||
$(INVOKE) ./$(CTARGET)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
@ -77,7 +89,10 @@ scrptrun.d: $(top_srcdir)/extra/scrptrun/scrptrun.cpp
|
||||
scrptrun.o: $(top_srcdir)/extra/scrptrun/scrptrun.cpp
|
||||
$(COMPILE.cc) $(DYNAMICCPPFLAGS) $(DYNAMICCXXFLAGS) -o $@ $<
|
||||
|
||||
$(TARGET) : $(OBJECTS)
|
||||
$(TARGET) : $(COMMON) $(OBJECTS)
|
||||
$(LINK.cc) -o $@ $^ $(LIBS)
|
||||
|
||||
$(CTARGET) : $(COMMON) $(COBJECTS)
|
||||
$(LINK.cc) -o $@ $^ $(LIBS)
|
||||
|
||||
invoke:
|
||||
|
22
icu4c/source/samples/layout/arraymem.h
Normal file
22
icu4c/source/samples/layout/arraymem.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARRAYMEM_H
|
||||
#define __ARRAYMEM_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
|
||||
|
||||
#define ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
|
||||
|
||||
#define NEW_ARRAY(type,count) (type *) malloc((count) * sizeof(type))
|
||||
|
||||
#define DELETE_ARRAY(array) free((void *) (array))
|
||||
|
||||
#define GROW_ARRAY(array,newSize) realloc((void *) (array), (newSize) * sizeof (array)[0])
|
||||
|
||||
#endif
|
342
icu4c/source/samples/layout/cgnomelayout.c
Normal file
342
icu4c/source/samples/layout/cgnomelayout.c
Normal file
@ -0,0 +1,342 @@
|
||||
|
||||
/*
|
||||
****************************************************************************** *
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
****************************************************************************** *
|
||||
*/
|
||||
|
||||
#include <gnome.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "pflow.h"
|
||||
|
||||
#include "gnomeglue.h"
|
||||
|
||||
#include "arraymem.h"
|
||||
|
||||
struct Context
|
||||
{
|
||||
long width;
|
||||
long height;
|
||||
pf_flow *paragraph;
|
||||
};
|
||||
|
||||
typedef struct Context Context;
|
||||
|
||||
static FT_Library engine;
|
||||
static gs_guiSupport *guiSupport;
|
||||
static fm_fontMap *fontMap;
|
||||
static le_font *font;
|
||||
|
||||
static GSList *appList = NULL;
|
||||
|
||||
GtkWidget *newSample(const gchar *fileName);
|
||||
void closeSample(GtkWidget *sample);
|
||||
|
||||
static void showabout(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget *aboutBox;
|
||||
const gchar *documentedBy[] = {NULL};
|
||||
const gchar *writtenBy[] = {
|
||||
"Eric Mader",
|
||||
NULL
|
||||
};
|
||||
|
||||
aboutBox = gnome_about_new("Gnome Layout Sample",
|
||||
"0.1",
|
||||
"Copyright (C) 1998-2006 By International Business Machines Corporation and others. All Rights Reserved.",
|
||||
"A simple demo of the ICU LayoutEngine.",
|
||||
writtenBy,
|
||||
documentedBy,
|
||||
"",
|
||||
NULL);
|
||||
|
||||
gtk_widget_show(aboutBox);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void notimpl(GtkObject *object, gpointer data)
|
||||
{
|
||||
gnome_ok_dialog("Not implemented...");
|
||||
}
|
||||
#endif
|
||||
|
||||
static gchar *prettyTitle(const gchar *path)
|
||||
{
|
||||
const gchar *name = g_basename(path);
|
||||
gchar *title = g_strconcat("Gnome Layout Sample - ", name, NULL);
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
static void openOK(GtkObject *object, gpointer data)
|
||||
{
|
||||
GtkFileSelection *fileselection = GTK_FILE_SELECTION(data);
|
||||
GtkWidget *app = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(fileselection), "app"));
|
||||
Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
|
||||
gchar *fileName = g_strdup(gtk_file_selection_get_filename(fileselection));
|
||||
pf_flow *newPara;
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(fileselection));
|
||||
|
||||
newPara = pf_factory(fileName, font, guiSupport);
|
||||
|
||||
if (newPara != NULL) {
|
||||
gchar *title = prettyTitle(fileName);
|
||||
GtkWidget *area = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(app), "area"));
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
pf_close(context->paragraph);
|
||||
}
|
||||
|
||||
context->paragraph = newPara;
|
||||
gtk_window_set_title(GTK_WINDOW(app), title);
|
||||
|
||||
gtk_widget_hide(area);
|
||||
pf_breakLines(context->paragraph, context->width, context->height);
|
||||
gtk_widget_show_all(area);
|
||||
|
||||
g_free(title);
|
||||
}
|
||||
|
||||
g_free(fileName);
|
||||
}
|
||||
|
||||
static void openfile(GtkObject *object, gpointer data)
|
||||
{
|
||||
GtkWidget *app = GTK_WIDGET(data);
|
||||
GtkWidget *fileselection;
|
||||
GtkWidget *okButton;
|
||||
GtkWidget *cancelButton;
|
||||
|
||||
fileselection =
|
||||
gtk_file_selection_new("Open File");
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(fileselection), "app", app);
|
||||
|
||||
okButton =
|
||||
GTK_FILE_SELECTION(fileselection)->ok_button;
|
||||
|
||||
cancelButton =
|
||||
GTK_FILE_SELECTION(fileselection)->cancel_button;
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(fileselection), "destroy",
|
||||
GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
||||
GTK_SIGNAL_FUNC(openOK), fileselection);
|
||||
|
||||
gtk_signal_connect_object(GTK_OBJECT(cancelButton), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fileselection));
|
||||
|
||||
gtk_window_set_modal(GTK_WINDOW(fileselection), TRUE);
|
||||
gtk_widget_show(fileselection);
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
static void newapp(GtkObject *object, gpointer data)
|
||||
{
|
||||
GtkWidget *app = newSample("Sample.txt");
|
||||
|
||||
gtk_widget_show_all(app);
|
||||
}
|
||||
|
||||
static void closeapp(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget *app = GTK_WIDGET(data);
|
||||
|
||||
closeSample(app);
|
||||
}
|
||||
|
||||
static void shutdown(GtkObject *object, gpointer data)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
GnomeUIInfo fileMenu[] =
|
||||
{
|
||||
GNOMEUIINFO_MENU_NEW_ITEM((gchar *) "_New Sample",
|
||||
(gchar *) "Create a new Gnome Layout Sample",
|
||||
newapp, NULL),
|
||||
|
||||
GNOMEUIINFO_MENU_OPEN_ITEM(openfile, NULL),
|
||||
GNOMEUIINFO_SEPARATOR,
|
||||
GNOMEUIINFO_MENU_CLOSE_ITEM(closeapp, NULL),
|
||||
GNOMEUIINFO_MENU_EXIT_ITEM(shutdown, NULL),
|
||||
GNOMEUIINFO_END
|
||||
};
|
||||
|
||||
GnomeUIInfo helpMenu[] =
|
||||
{
|
||||
/* GNOMEUIINFO_HELP("gnomelayout"), */
|
||||
GNOMEUIINFO_MENU_ABOUT_ITEM(showabout, NULL),
|
||||
GNOMEUIINFO_END
|
||||
};
|
||||
|
||||
GnomeUIInfo mainMenu[] =
|
||||
{
|
||||
GNOMEUIINFO_SUBTREE(N_((gchar *) "File"), fileMenu),
|
||||
GNOMEUIINFO_SUBTREE(N_((gchar *) "Help"), helpMenu),
|
||||
GNOMEUIINFO_END
|
||||
};
|
||||
|
||||
static gint eventDelete(GtkWidget *widget, GdkEvent *event, gpointer data)
|
||||
{
|
||||
closeSample(widget);
|
||||
|
||||
/* indicate that closeapp already destroyed the window */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint eventConfigure(GtkWidget *widget, GdkEventConfigure *event, Context *context)
|
||||
{
|
||||
if (context->paragraph != NULL) {
|
||||
context->width = event->width;
|
||||
context->height = event->height;
|
||||
|
||||
if (context->width > 0 && context->height > 0) {
|
||||
pf_breakLines(context->paragraph, context->width, context->height);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint eventExpose(GtkWidget *widget, GdkEvent *event, Context *context)
|
||||
{
|
||||
if (context->paragraph != NULL) {
|
||||
gint maxLines = pf_getLineCount(context->paragraph) - 1;
|
||||
gint firstLine = 0, lastLine = context->height / pf_getLineHeight(context->paragraph);
|
||||
rs_surface *surface = rs_gnomeRenderingSurfaceOpen(widget);
|
||||
|
||||
pf_draw(context->paragraph, surface, firstLine, (maxLines < lastLine)? maxLines : lastLine);
|
||||
|
||||
rs_gnomeRenderingSurfaceClose(surface);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *newSample(const gchar *fileName)
|
||||
{
|
||||
Context *context = NEW_ARRAY(Context, 1);
|
||||
gchar *title;
|
||||
GtkWidget *app;
|
||||
GtkWidget *area;
|
||||
GtkStyle *style;
|
||||
int i;
|
||||
|
||||
context->width = 600;
|
||||
context->height = 400;
|
||||
context->paragraph = pf_factory(fileName, font, guiSupport);
|
||||
|
||||
title = prettyTitle(fileName);
|
||||
app = gnome_app_new("gnomeLayout", title);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(app), "context", context);
|
||||
|
||||
gtk_window_set_default_size(GTK_WINDOW(app), 600 - 24, 400);
|
||||
|
||||
gnome_app_create_menus_with_data(GNOME_APP(app), mainMenu, app);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(app), "delete_event",
|
||||
GTK_SIGNAL_FUNC(eventDelete), NULL);
|
||||
|
||||
area = gtk_drawing_area_new();
|
||||
gtk_object_set_data(GTK_OBJECT(app), "area", area);
|
||||
|
||||
style = gtk_style_copy(gtk_widget_get_style(area));
|
||||
|
||||
for (i = 0; i < 5; i += 1) {
|
||||
style->fg[i] = style->white;
|
||||
}
|
||||
|
||||
gtk_widget_set_style(area, style);
|
||||
|
||||
gnome_app_set_contents(GNOME_APP(app), area);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(area),
|
||||
"expose_event",
|
||||
GTK_SIGNAL_FUNC(eventExpose),
|
||||
context);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(area),
|
||||
"configure_event",
|
||||
GTK_SIGNAL_FUNC(eventConfigure),
|
||||
context);
|
||||
|
||||
appList = g_slist_prepend(appList, app);
|
||||
|
||||
g_free(title);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void closeSample(GtkWidget *app)
|
||||
{
|
||||
Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
pf_close(context->paragraph);
|
||||
}
|
||||
|
||||
DELETE_ARRAY(context);
|
||||
|
||||
appList = g_slist_remove(appList, app);
|
||||
|
||||
gtk_widget_destroy(app);
|
||||
|
||||
if (appList == NULL) {
|
||||
gtk_main_quit();
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
LEErrorCode fontStatus = LE_NO_ERROR;
|
||||
poptContext ptctx;
|
||||
GtkWidget *app;
|
||||
const char *defaultArgs[] = {"Sample.txt", NULL};
|
||||
const char **args;
|
||||
int i;
|
||||
|
||||
FT_Init_FreeType(&engine);
|
||||
|
||||
gnome_init_with_popt_table("gnomelayout", "0.1", argc, argv, NULL, 0, &ptctx);
|
||||
|
||||
guiSupport = gs_gnomeGuiSupportOpen();
|
||||
fontMap = fm_gnomeFontMapOpen(engine, "FontMap.Gnome", 24, guiSupport, &fontStatus);
|
||||
font = le_scriptCompositeFontOpen(fontMap);
|
||||
|
||||
if (LE_FAILURE(fontStatus)) {
|
||||
FT_Done_FreeType(engine);
|
||||
return 1;
|
||||
}
|
||||
|
||||
args = poptGetArgs(ptctx);
|
||||
|
||||
if (args == NULL) {
|
||||
args = defaultArgs;
|
||||
}
|
||||
|
||||
for (i = 0; args[i] != NULL; i += 1) {
|
||||
app = newSample(args[i]);
|
||||
|
||||
gtk_widget_show_all(app);
|
||||
}
|
||||
|
||||
poptFreeContext(ptctx);
|
||||
|
||||
gtk_main();
|
||||
|
||||
le_fontClose(font);
|
||||
gs_gnomeGuiSupportClose(guiSupport);
|
||||
|
||||
FT_Done_FreeType(engine);
|
||||
|
||||
exit(0);
|
||||
}
|
363
icu4c/source/samples/layout/clayout.c
Normal file
363
icu4c/source/samples/layout/clayout.c
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: Layout.cpp
|
||||
*
|
||||
* created on: 08/03/2000
|
||||
* created by: Eric R. Mader
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "playout.h"
|
||||
#include "pflow.h"
|
||||
|
||||
#include "gdiglue.h"
|
||||
#include "ucreader.h"
|
||||
|
||||
#include "arraymem.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
struct Context
|
||||
{
|
||||
le_int32 width;
|
||||
le_int32 height;
|
||||
pf_flow *paragraph;
|
||||
};
|
||||
|
||||
typedef struct Context Context;
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
#define APP_NAME "LayoutSample"
|
||||
|
||||
TCHAR szAppName[] = TEXT(APP_NAME);
|
||||
|
||||
void PrettyTitle(HWND hwnd, char *fileName)
|
||||
{
|
||||
char title[MAX_PATH + 64];
|
||||
|
||||
sprintf(title, "%s - %s", APP_NAME, fileName);
|
||||
|
||||
SetWindowTextA(hwnd, title);
|
||||
}
|
||||
|
||||
void InitParagraph(HWND hwnd, Context *context)
|
||||
{
|
||||
SCROLLINFO si;
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
// FIXME: does it matter what we put in the ScrollInfo
|
||||
// if the window's been minimized?
|
||||
if (context->width > 0 && context->height > 0) {
|
||||
pf_breakLines(context->paragraph, context->width, context->height);
|
||||
}
|
||||
|
||||
si.cbSize = sizeof si;
|
||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
|
||||
si.nMin = 0;
|
||||
si.nMax = pf_getLineCount(context->paragraph) - 1;
|
||||
si.nPage = context->height / pf_getLineHeight(context->paragraph);
|
||||
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
|
||||
{
|
||||
HWND hwnd;
|
||||
HACCEL hAccel;
|
||||
MSG msg;
|
||||
WNDCLASS wndclass;
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wndclass.lpfnWndProc = WndProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = sizeof(LONG);
|
||||
wndclass.hInstance = hInstance;
|
||||
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
|
||||
wndclass.lpszMenuName = szAppName;
|
||||
wndclass.lpszClassName = szAppName;
|
||||
|
||||
if (!RegisterClass(&wndclass)) {
|
||||
MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
hAccel = LoadAccelerators(hInstance, szAppName);
|
||||
|
||||
hwnd = CreateWindow(szAppName, NULL,
|
||||
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
600, 400,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
|
||||
ShowWindow(hwnd, iCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
if (!TranslateAccelerator(hwnd, hAccel, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
UnregisterClass(szAppName, hInstance);
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
Context *context;
|
||||
static le_int32 windowCount = 0;
|
||||
static fm_fontMap *fontMap = NULL;
|
||||
static rs_surface *surface = NULL;
|
||||
static gs_guiSupport *guiSupport = NULL;
|
||||
static le_font *font = NULL;
|
||||
|
||||
switch (message) {
|
||||
case WM_CREATE:
|
||||
{
|
||||
LEErrorCode fontStatus = LE_NO_ERROR;
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
guiSupport = gs_gdiGuiSupportOpen();
|
||||
surface = rs_gdiRenderingSurfaceOpen(hdc);
|
||||
|
||||
fontMap = fm_gdiFontMapOpen(surface, "FontMap.GDI", 24, guiSupport, &fontStatus);
|
||||
font = le_scriptCompositeFontOpen(fontMap);
|
||||
|
||||
if (LE_FAILURE(fontStatus)) {
|
||||
ReleaseDC(hwnd, hdc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
context = NEW_ARRAY(Context, 1);
|
||||
|
||||
context->width = 600;
|
||||
context->height = 400;
|
||||
|
||||
context->paragraph = pf_factory("Sample.txt", font, guiSupport);
|
||||
SetWindowLongPtr(hwnd, 0, (LONG_PTR) context);
|
||||
|
||||
windowCount += 1;
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
PrettyTitle(hwnd, "Sample.txt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
context->width = LOWORD(lParam);
|
||||
context->height = HIWORD(lParam);
|
||||
|
||||
InitParagraph(hwnd, context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_VSCROLL:
|
||||
{
|
||||
SCROLLINFO si;
|
||||
le_int32 vertPos;
|
||||
|
||||
si.cbSize = sizeof si;
|
||||
si.fMask = SIF_ALL;
|
||||
GetScrollInfo(hwnd, SB_VERT, &si);
|
||||
|
||||
vertPos = si.nPos;
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case SB_TOP:
|
||||
si.nPos = si.nMin;
|
||||
break;
|
||||
|
||||
case SB_BOTTOM:
|
||||
si.nPos = si.nMax;
|
||||
break;
|
||||
|
||||
case SB_LINEUP:
|
||||
si.nPos -= 1;
|
||||
break;
|
||||
|
||||
case SB_LINEDOWN:
|
||||
si.nPos += 1;
|
||||
break;
|
||||
|
||||
case SB_PAGEUP:
|
||||
si.nPos -= si.nPage;
|
||||
break;
|
||||
|
||||
case SB_PAGEDOWN:
|
||||
si.nPos += si.nPage;
|
||||
break;
|
||||
|
||||
case SB_THUMBTRACK:
|
||||
si.nPos = si.nTrackPos;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
si.fMask = SIF_POS;
|
||||
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
|
||||
GetScrollInfo(hwnd, SB_VERT, &si);
|
||||
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL && si.nPos != vertPos) {
|
||||
ScrollWindow(hwnd, 0, pf_getLineHeight(context->paragraph) * (vertPos - si.nPos), NULL, NULL);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
SCROLLINFO si;
|
||||
le_int32 firstLine, lastLine;
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
|
||||
si.cbSize = sizeof si;
|
||||
si.fMask = SIF_ALL;
|
||||
GetScrollInfo(hwnd, SB_VERT, &si);
|
||||
|
||||
firstLine = si.nPos;
|
||||
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
rs_gdiRenderingSurfaceSetHDC(surface, hdc);
|
||||
|
||||
// NOTE: si.nPos + si.nPage may include a partial line at the bottom
|
||||
// of the window. We need this because scrolling assumes that the
|
||||
// partial line has been painted.
|
||||
lastLine = min (si.nPos + (le_int32) si.nPage, pf_getLineCount(context->paragraph) - 1);
|
||||
|
||||
pf_draw(context->paragraph, surface, firstLine, lastLine);
|
||||
}
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDM_FILE_OPEN:
|
||||
{
|
||||
OPENFILENAMEA ofn;
|
||||
char szFileName[MAX_PATH], szTitleName[MAX_PATH];
|
||||
static char szFilter[] = "Text Files (.txt)\0*.txt\0"
|
||||
"All Files (*.*)\0*.*\0\0";
|
||||
|
||||
ofn.lStructSize = sizeof (OPENFILENAMEA);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.hInstance = NULL;
|
||||
ofn.lpstrFilter = szFilter;
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.nFilterIndex = 0;
|
||||
ofn.lpstrFile = szFileName;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.lpstrFileTitle = szTitleName;
|
||||
ofn.nMaxFileTitle = MAX_PATH;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.lpstrTitle = NULL;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
|
||||
ofn.nFileOffset = 0;
|
||||
ofn.nFileExtension = 0;
|
||||
ofn.lpstrDefExt = "txt";
|
||||
ofn.lCustData = 0L;
|
||||
ofn.lpfnHook = NULL;
|
||||
ofn.lpTemplateName = NULL;
|
||||
|
||||
szFileName[0] = '\0';
|
||||
|
||||
if (GetOpenFileNameA(&ofn)) {
|
||||
pf_flow *newParagraph;
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
rs_gdiRenderingSurfaceSetHDC(surface, hdc);
|
||||
|
||||
newParagraph = pf_factory(szFileName, font, guiSupport);
|
||||
|
||||
if (newParagraph != NULL) {
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
pf_close(context->paragraph);
|
||||
}
|
||||
|
||||
context->paragraph = newParagraph;
|
||||
InitParagraph(hwnd, context);
|
||||
PrettyTitle(hwnd, szTitleName);
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//ReleaseDC(hwnd, hdc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case IDM_FILE_EXIT:
|
||||
case IDM_FILE_CLOSE:
|
||||
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
return 0;
|
||||
|
||||
case IDM_HELP_ABOUTLAYOUTSAMPLE:
|
||||
MessageBox(hwnd, TEXT("Windows Layout Sample 0.1\n")
|
||||
TEXT("Copyright (C) 1998-2005 By International Business Machines Corporation and others.\n")
|
||||
TEXT("Author: Eric Mader"),
|
||||
szAppName, MB_ICONINFORMATION | MB_OK);
|
||||
return 0;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context != NULL && context->paragraph != NULL) {
|
||||
pf_close(context->paragraph);
|
||||
}
|
||||
|
||||
DELETE_ARRAY(context);
|
||||
|
||||
if (--windowCount <= 0) {
|
||||
le_fontClose(font);
|
||||
rs_gdiRenderingSurfaceClose(surface);
|
||||
gs_gdiGuiSupportClose(guiSupport);
|
||||
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
80
icu4c/source/samples/layout/gdiglue.cpp
Normal file
80
icu4c/source/samples/layout/gdiglue.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "loengine.h"
|
||||
#include "rsurface.h"
|
||||
#include "gsupport.h"
|
||||
|
||||
#include "gdiglue.h"
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "GDIGUISupport.h"
|
||||
#include "GDIFontMap.h"
|
||||
#include "ScriptCompositeFontInstance.h"
|
||||
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
gs_guiSupport *gs_gdiGuiSupportOpen()
|
||||
{
|
||||
return (gs_guiSupport *) new GDIGUISupport();
|
||||
}
|
||||
|
||||
void gs_gdiGuiSupportClose(gs_guiSupport *guiSupport)
|
||||
{
|
||||
GDIGUISupport *gs = (GDIGUISupport *) guiSupport;
|
||||
|
||||
delete gs;
|
||||
}
|
||||
|
||||
rs_surface *rs_gdiRenderingSurfaceOpen(HDC hdc)
|
||||
{
|
||||
return (rs_surface *) new GDISurface(hdc);
|
||||
}
|
||||
|
||||
void rs_gdiRenderingSurfaceSetHDC(rs_surface *surface, HDC hdc)
|
||||
{
|
||||
GDISurface *rs = (GDISurface *) surface;
|
||||
|
||||
rs->setHDC(hdc);
|
||||
}
|
||||
|
||||
void rs_gdiRenderingSurfaceClose(rs_surface *surface)
|
||||
{
|
||||
GDISurface *rs = (GDISurface *) surface;
|
||||
|
||||
delete rs;
|
||||
}
|
||||
|
||||
fm_fontMap *fm_gdiFontMapOpen(rs_surface *surface, const char *fileName, le_int16 pointSize, gs_guiSupport *guiSupport, LEErrorCode *status)
|
||||
{
|
||||
return (fm_fontMap *) new GDIFontMap((GDISurface *) surface, fileName, pointSize, (GDIGUISupport *) guiSupport, *status);
|
||||
}
|
||||
|
||||
void fm_fontMapClose(fm_fontMap *fontMap)
|
||||
{
|
||||
GDIFontMap *fm = (GDIFontMap *) fontMap;
|
||||
|
||||
delete fm;
|
||||
}
|
||||
|
||||
le_font *le_scriptCompositeFontOpen(fm_fontMap *fontMap)
|
||||
{
|
||||
return (le_font *) new ScriptCompositeFontInstance((FontMap *) fontMap);
|
||||
}
|
||||
|
||||
void le_fontClose(le_font *font)
|
||||
{
|
||||
LEFontInstance *fi = (LEFontInstance *) font;
|
||||
|
||||
delete fi;
|
||||
}
|
||||
|
||||
U_CDECL_END
|
38
icu4c/source/samples/layout/gdiglue.h
Normal file
38
icu4c/source/samples/layout/gdiglue.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDIGLUE_H
|
||||
#define __GDIGLUE_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
#include "gsupport.h"
|
||||
#include "rsurface.h"
|
||||
|
||||
typedef void fm_fontMap;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
gs_guiSupport *gs_gdiGuiSupportOpen();
|
||||
void gs_gdiGuiSupportClose(gs_guiSupport *guiSupport);
|
||||
|
||||
rs_surface *rs_gdiRenderingSurfaceOpen(HDC hdc);
|
||||
void rs_gdiRenderingSurfaceSetHDC(rs_surface *surface, HDC hdc);
|
||||
void rs_gdiRenderingSurfaceClose(rs_surface *surface);
|
||||
|
||||
fm_fontMap *fm_gdiFontMapOpen(rs_surface *surface, const char *fileName, le_int16 pointSize, gs_guiSupport *guiSupport, LEErrorCode *status);
|
||||
void fm_fontMapClose(fm_fontMap *fontMap);
|
||||
|
||||
le_font *le_scriptCompositeFontOpen(fm_fontMap *fontMap);
|
||||
void le_fontClose(le_font *font);
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
#endif
|
76
icu4c/source/samples/layout/gnomeglue.cpp
Normal file
76
icu4c/source/samples/layout/gnomeglue.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gnome.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "loengine.h"
|
||||
#include "rsurface.h"
|
||||
#include "gsupport.h"
|
||||
|
||||
#include "gnomeglue.h"
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "GnomeGUISupport.h"
|
||||
#include "GnomeFontMap.h"
|
||||
#include "GnomeFontInstance.h"
|
||||
#include "ScriptCompositeFontInstance.h"
|
||||
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
gs_guiSupport *gs_gnomeGuiSupportOpen()
|
||||
{
|
||||
return (gs_guiSupport *) new GnomeGUISupport();
|
||||
}
|
||||
|
||||
void gs_gnomeGuiSupportClose(gs_guiSupport *guiSupport)
|
||||
{
|
||||
GnomeGUISupport *gs = (GnomeGUISupport *) guiSupport;
|
||||
|
||||
delete gs;
|
||||
}
|
||||
|
||||
rs_surface *rs_gnomeRenderingSurfaceOpen(GtkWidget *theWidget)
|
||||
{
|
||||
return (rs_surface *) new GnomeSurface(theWidget);
|
||||
}
|
||||
|
||||
void rs_gnomeRenderingSurfaceClose(rs_surface *surface)
|
||||
{
|
||||
GnomeSurface *rs = (GnomeSurface *) surface;
|
||||
|
||||
delete rs;
|
||||
}
|
||||
|
||||
fm_fontMap *fm_gnomeFontMapOpen(FT_Library engine, const char *fileName, le_int16 pointSize, gs_guiSupport *guiSupport, LEErrorCode *status)
|
||||
{
|
||||
return (fm_fontMap *) new GnomeFontMap(engine, fileName, pointSize, (GnomeGUISupport *) guiSupport, *status);
|
||||
}
|
||||
|
||||
void fm_fontMapClose(fm_fontMap *fontMap)
|
||||
{
|
||||
GnomeFontMap *fm = (GnomeFontMap *) fontMap;
|
||||
|
||||
delete fm;
|
||||
}
|
||||
|
||||
le_font *le_scriptCompositeFontOpen(fm_fontMap *fontMap)
|
||||
{
|
||||
return (le_font *) new ScriptCompositeFontInstance((FontMap *) fontMap);
|
||||
}
|
||||
|
||||
void le_fontClose(le_font *font)
|
||||
{
|
||||
LEFontInstance *fi = (LEFontInstance *) font;
|
||||
|
||||
delete fi;
|
||||
}
|
||||
|
||||
U_CDECL_END
|
39
icu4c/source/samples/layout/gnomeglue.h
Normal file
39
icu4c/source/samples/layout/gnomeglue.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GNOMEGLUE_H
|
||||
#define __GNOMEGLUE_H
|
||||
|
||||
#include <gnome.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
#include "gsupport.h"
|
||||
#include "rsurface.h"
|
||||
|
||||
typedef void fm_fontMap;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
gs_guiSupport *gs_gnomeGuiSupportOpen();
|
||||
void gs_gnomeGuiSupportClose(gs_guiSupport *guiSupport);
|
||||
|
||||
rs_surface *rs_gnomeRenderingSurfaceOpen(GtkWidget *theWidget);
|
||||
void rs_gnomeRenderingSurfaceClose(rs_surface *surface);
|
||||
|
||||
fm_fontMap *fm_gnomeFontMapOpen(FT_Library engine, const char *fileName, le_int16 pointSize, gs_guiSupport *guiSupport, LEErrorCode *status);
|
||||
void fm_fontMapClose(fm_fontMap *fontMap);
|
||||
|
||||
le_font *le_scriptCompositeFontOpen(fm_fontMap *fontMap);
|
||||
void le_fontClose(le_font *font);
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
#endif
|
14
icu4c/source/samples/layout/gsupport.h
Normal file
14
icu4c/source/samples/layout/gsupport.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GSUPPORT_H
|
||||
#define __GSUPPORT_H
|
||||
|
||||
typedef void gs_guiSupport;
|
||||
|
||||
void gs_postErrorMessage(gs_guiSupport *guiSupport, const char *message, const char *title);
|
||||
|
||||
#endif
|
@ -146,7 +146,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
context->height = 400;
|
||||
|
||||
context->paragraph = Paragraph::paragraphFactory("Sample.txt", font, guiSupport);
|
||||
SetWindowLong(hwnd, 0, (LONG) context);
|
||||
SetWindowLongPtr(hwnd, 0, (LONG_PTR) context);
|
||||
|
||||
windowCount += 1;
|
||||
ReleaseDC(hwnd, hdc);
|
||||
@ -157,7 +157,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
context = (Context *) GetWindowLong(hwnd, 0);
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
context->width = LOWORD(lParam);
|
||||
context->height = HIWORD(lParam);
|
||||
|
||||
@ -214,7 +214,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
|
||||
GetScrollInfo(hwnd, SB_VERT, &si);
|
||||
|
||||
context = (Context *) GetWindowLong(hwnd, 0);
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL && si.nPos != vertPos) {
|
||||
ScrollWindow(hwnd, 0, context->paragraph->getLineHeight() * (vertPos - si.nPos), NULL, NULL);
|
||||
@ -239,7 +239,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
firstLine = si.nPos;
|
||||
|
||||
context = (Context *) GetWindowLong(hwnd, 0);
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
surface->setHDC(hdc);
|
||||
@ -295,7 +295,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
Paragraph *newParagraph = Paragraph::paragraphFactory(szFileName, font, guiSupport);
|
||||
|
||||
if (newParagraph != NULL) {
|
||||
context = (Context *) GetWindowLong(hwnd, 0);
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context->paragraph != NULL) {
|
||||
delete context->paragraph;
|
||||
@ -332,7 +332,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
context = (Context *) GetWindowLong(hwnd, 0);
|
||||
context = (Context *) GetWindowLongPtr(hwnd, 0);
|
||||
|
||||
if (context != NULL && context->paragraph != NULL) {
|
||||
delete context->paragraph;
|
||||
|
@ -3,7 +3,7 @@
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="layout"
|
||||
ProjectGUID="{EE80B3B5-40F2-46F2-AC4B-FB929683515C}"
|
||||
ProjectGUID="{497500ED-DE1D-4B20-B529-F41B5A0FBEEB}"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -19,11 +19,9 @@
|
||||
#include "layout/ParagraphLayout.h"
|
||||
|
||||
#include "RenderingSurface.h"
|
||||
#include "ScriptCompositeFontInstance.h"
|
||||
|
||||
#include "paragraph.h"
|
||||
#include "UnicodeReader.h"
|
||||
#include "FontMap.h"
|
||||
|
||||
#define MARGIN 10
|
||||
#define LINE_GROW 32
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -21,7 +21,6 @@
|
||||
|
||||
#include "GUISupport.h"
|
||||
#include "RenderingSurface.h"
|
||||
//#include "FontMap.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
|
381
icu4c/source/samples/layout/pflow.c
Normal file
381
icu4c/source/samples/layout/pflow.c
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uchar.h"
|
||||
#include "unicode/ubidi.h"
|
||||
#include "unicode/ustring.h"
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
|
||||
#include "layout/loengine.h"
|
||||
#include "layout/playout.h"
|
||||
#include "layout/plruns.h"
|
||||
|
||||
#include "pflow.h"
|
||||
|
||||
#include "arraymem.h"
|
||||
#include "ucreader.h"
|
||||
|
||||
/*
|
||||
* Move the line below out of this comment
|
||||
* to add a locale run to the pl_paragraphs
|
||||
* that are created.
|
||||
#define TEST_LOCALE "zh_TW"
|
||||
*/
|
||||
|
||||
#define MARGIN 10
|
||||
#define LINE_GROW 32
|
||||
#define PARA_GROW 8
|
||||
|
||||
#define CH_LF 0x000A
|
||||
#define CH_CR 0x000D
|
||||
#define CH_LSEP 0x2028
|
||||
#define CH_PSEP 0x2029
|
||||
|
||||
struct pf_object
|
||||
{
|
||||
pl_paragraph **fParagraphLayout;
|
||||
|
||||
le_int32 fParagraphCount;
|
||||
le_int32 fParagraphMax;
|
||||
le_int32 fParagraphGrow;
|
||||
|
||||
le_int32 fLineCount;
|
||||
le_int32 fLinesMax;
|
||||
le_int32 fLinesGrow;
|
||||
|
||||
pl_line **fLines;
|
||||
|
||||
LEUnicode *fChars;
|
||||
|
||||
le_int32 fLineHeight;
|
||||
le_int32 fAscent;
|
||||
le_int32 fWidth;
|
||||
le_int32 fHeight;
|
||||
UBiDiLevel fParagraphLevel;
|
||||
};
|
||||
|
||||
typedef struct pf_object pf_object;
|
||||
|
||||
|
||||
static LEUnicode *skipLineEnd(LEUnicode *ptr)
|
||||
{
|
||||
if (ptr[0] == CH_CR && ptr[1] == CH_LF) {
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
return ptr + 1;
|
||||
}
|
||||
|
||||
static le_int32 findFontRun(const pl_fontRuns *fontRuns, le_int32 offset)
|
||||
{
|
||||
le_int32 runCount = pl_getFontRunCount(fontRuns);
|
||||
le_int32 run;
|
||||
|
||||
for (run = 0; run < runCount; run += 1) {
|
||||
if (pl_getFontRunLimit(fontRuns, run) > offset) {
|
||||
return run;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void subsetFontRuns(const pl_fontRuns *fontRuns, le_int32 start, le_int32 limit, pl_fontRuns *sub)
|
||||
{
|
||||
le_int32 startRun = findFontRun(fontRuns, start);
|
||||
le_int32 endRun = findFontRun(fontRuns, limit - 1);
|
||||
le_int32 run;
|
||||
|
||||
pl_resetFontRuns(sub);
|
||||
|
||||
for (run = startRun; run <= endRun; run += 1) {
|
||||
const le_font *runFont = pl_getFontRunFont(fontRuns, run);
|
||||
le_int32 runLimit = pl_getFontRunLimit(fontRuns, run) - start;
|
||||
|
||||
if (run == endRun) {
|
||||
runLimit = limit - start;
|
||||
}
|
||||
|
||||
pl_addFontRun(sub, runFont, runLimit);
|
||||
}
|
||||
}
|
||||
|
||||
pf_flow *pf_create(const LEUnicode chars[], le_int32 charCount, const pl_fontRuns *fontRuns, LEErrorCode *status)
|
||||
{
|
||||
pf_object *flow;
|
||||
le_int32 ascent = 0;
|
||||
le_int32 descent = 0;
|
||||
le_int32 leading = 0;
|
||||
pl_localeRuns *locales = NULL;
|
||||
pl_fontRuns *fr;
|
||||
LEUnicode *pStart;
|
||||
static const LEUnicode separators[] = {CH_LF, CH_CR, CH_LSEP, CH_PSEP, 0x0000};
|
||||
|
||||
if (LE_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flow = NEW_ARRAY(pf_object, 1);
|
||||
|
||||
flow->fParagraphLayout = NULL;
|
||||
flow->fParagraphCount = 0;
|
||||
flow->fParagraphMax = PARA_GROW;
|
||||
flow->fParagraphGrow = PARA_GROW;
|
||||
flow->fLineCount = 0;
|
||||
flow->fLinesMax = LINE_GROW;
|
||||
flow->fLinesGrow = LINE_GROW;
|
||||
flow->fLines = NULL;
|
||||
flow->fChars = NULL;
|
||||
flow->fLineHeight = -1;
|
||||
flow->fAscent = -1;
|
||||
flow->fWidth = -1;
|
||||
flow->fHeight = -1;
|
||||
flow->fParagraphLevel = UBIDI_DEFAULT_LTR;
|
||||
|
||||
fr = pl_openEmptyFontRuns(0);
|
||||
|
||||
#ifdef TEST_LOCALE
|
||||
locales = pl_openEmptyLocaleRuns(0);
|
||||
#endif
|
||||
|
||||
flow->fLines = NEW_ARRAY(pl_line *, flow->fLinesMax);
|
||||
flow->fParagraphLayout = NEW_ARRAY(pl_paragraph *, flow->fParagraphMax);
|
||||
|
||||
flow->fChars = NEW_ARRAY(LEUnicode, charCount + 1);
|
||||
LE_ARRAY_COPY(flow->fChars, chars, charCount);
|
||||
flow->fChars[charCount] = 0;
|
||||
|
||||
pStart = &flow->fChars[0];
|
||||
|
||||
while (*pStart != 0) {
|
||||
LEUnicode *pEnd = u_strpbrk(pStart, separators);
|
||||
le_int32 pAscent, pDescent, pLeading;
|
||||
pl_paragraph *paragraphLayout = NULL;
|
||||
|
||||
if (pEnd == NULL) {
|
||||
pEnd = &flow->fChars[charCount];
|
||||
}
|
||||
|
||||
if (pEnd != pStart) {
|
||||
subsetFontRuns(fontRuns, pStart - flow->fChars, pEnd - flow->fChars, fr);
|
||||
|
||||
#ifdef TEST_LOCALE
|
||||
pl_resetLocaleRuns(locales);
|
||||
pl_addLocaleRun(locales, TEST_LOCALE, pEnd - pStart);
|
||||
#endif
|
||||
|
||||
paragraphLayout = pl_create(pStart, pEnd - pStart, fr, NULL, NULL, locales, flow->fParagraphLevel, FALSE, status);
|
||||
|
||||
if (LE_FAILURE(*status)) {
|
||||
break; /* return? something else? */
|
||||
}
|
||||
|
||||
if (flow->fParagraphLevel == UBIDI_DEFAULT_LTR) {
|
||||
flow->fParagraphLevel = pl_getParagraphLevel(paragraphLayout);
|
||||
}
|
||||
|
||||
pAscent = pl_getAscent(paragraphLayout);
|
||||
pDescent = pl_getDescent(paragraphLayout);
|
||||
pLeading = pl_getLeading(paragraphLayout);
|
||||
|
||||
if (pAscent > ascent) {
|
||||
ascent = pAscent;
|
||||
}
|
||||
|
||||
if (pDescent > descent) {
|
||||
descent = pDescent;
|
||||
}
|
||||
|
||||
if (pLeading > leading) {
|
||||
leading = pLeading;
|
||||
}
|
||||
}
|
||||
|
||||
if (flow->fParagraphCount >= flow->fParagraphMax) {
|
||||
flow->fParagraphLayout = (pl_paragraph **) GROW_ARRAY(flow->fParagraphLayout, flow->fParagraphMax + flow->fParagraphGrow);
|
||||
flow->fParagraphMax += flow->fParagraphGrow;
|
||||
}
|
||||
|
||||
flow->fParagraphLayout[flow->fParagraphCount++] = paragraphLayout;
|
||||
|
||||
if (*pEnd == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pStart = skipLineEnd(pEnd);
|
||||
}
|
||||
|
||||
flow->fLineHeight = ascent + descent + leading;
|
||||
flow->fAscent = ascent;
|
||||
|
||||
pl_closeLocaleRuns(locales);
|
||||
pl_closeFontRuns(fr);
|
||||
|
||||
return (pf_flow *) flow;
|
||||
}
|
||||
|
||||
void pf_close(pf_flow *flow)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
le_int32 i;
|
||||
|
||||
for (i = 0; i < obj->fLineCount; i += 1) {
|
||||
DELETE_ARRAY(obj->fLines[i]);
|
||||
}
|
||||
|
||||
DELETE_ARRAY(obj->fLines);
|
||||
|
||||
for (i = 0; i < obj->fParagraphCount; i += 1) {
|
||||
pl_close(obj->fParagraphLayout[i]);
|
||||
}
|
||||
|
||||
DELETE_ARRAY(obj->fParagraphLayout);
|
||||
|
||||
DELETE_ARRAY(obj->fChars);
|
||||
|
||||
DELETE_ARRAY(obj);
|
||||
}
|
||||
|
||||
|
||||
le_int32 pf_getAscent(pf_flow *flow)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
|
||||
return obj->fAscent;
|
||||
}
|
||||
|
||||
le_int32 pf_getLineHeight(pf_flow *flow)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
|
||||
return obj->fLineHeight;
|
||||
}
|
||||
|
||||
le_int32 pf_getLineCount(pf_flow *flow)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
|
||||
return obj->fLineCount;
|
||||
}
|
||||
|
||||
static void addLine(pf_object *obj, pl_line *line)
|
||||
{
|
||||
if (obj->fLineCount >= obj->fLinesMax) {
|
||||
obj->fLines = (pl_line **) GROW_ARRAY(obj->fLines, obj->fLinesMax + obj->fLinesGrow);
|
||||
obj->fLinesMax += obj->fLinesGrow;
|
||||
}
|
||||
|
||||
obj->fLines[obj->fLineCount++] = line;
|
||||
}
|
||||
|
||||
void pf_breakLines(pf_flow *flow, le_int32 width, le_int32 height)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
le_int32 li, p;
|
||||
float lineWidth;
|
||||
pl_line *line;
|
||||
|
||||
obj->fHeight = height;
|
||||
|
||||
/* don't re-break if the width hasn't changed */
|
||||
if (obj->fWidth == width) {
|
||||
return;
|
||||
}
|
||||
|
||||
obj->fWidth = width;
|
||||
|
||||
lineWidth = (float) (width - 2 * MARGIN);
|
||||
|
||||
/* Free the old Lines... */
|
||||
for (li = 0; li < obj->fLineCount; li += 1) {
|
||||
pl_closeLine(obj->fLines[li]);
|
||||
}
|
||||
|
||||
obj->fLineCount = 0;
|
||||
|
||||
for (p = 0; p < obj->fParagraphCount; p += 1) {
|
||||
pl_paragraph *paragraphLayout = obj->fParagraphLayout[p];
|
||||
|
||||
if (paragraphLayout != NULL) {
|
||||
pl_reflow(paragraphLayout);
|
||||
while ((line = pl_nextLine(paragraphLayout, lineWidth)) != NULL) {
|
||||
addLine(obj, line);
|
||||
}
|
||||
} else {
|
||||
addLine(obj, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pf_draw(pf_flow *flow, rs_surface *surface, le_int32 firstLine, le_int32 lastLine)
|
||||
{
|
||||
pf_object *obj = (pf_object *) flow;
|
||||
le_int32 li, x, y;
|
||||
|
||||
x = MARGIN;
|
||||
y = obj->fAscent;
|
||||
|
||||
for (li = firstLine; li <= lastLine; li += 1) {
|
||||
const pl_line *line = obj->fLines[li];
|
||||
|
||||
if (line != NULL) {
|
||||
le_int32 runCount = pl_countLineRuns(line);
|
||||
le_int32 run;
|
||||
|
||||
if (obj->fParagraphLevel == UBIDI_RTL) {
|
||||
le_int32 lastX = pl_getLineWidth(line);
|
||||
|
||||
x = (obj->fWidth - lastX - MARGIN);
|
||||
}
|
||||
|
||||
|
||||
for (run = 0; run < runCount; run += 1) {
|
||||
const pl_visualRun *visualRun = pl_getLineVisualRun(line, run);
|
||||
le_int32 glyphCount = pl_getVisualRunGlyphCount(visualRun);
|
||||
const le_font *font = pl_getVisualRunFont(visualRun);
|
||||
const LEGlyphID *glyphs = pl_getVisualRunGlyphs(visualRun);
|
||||
const float *positions = pl_getVisualRunPositions(visualRun);
|
||||
|
||||
rs_drawGlyphs(surface, font, glyphs, glyphCount, positions, x, y, obj->fWidth, obj->fHeight);
|
||||
}
|
||||
}
|
||||
|
||||
y += obj->fLineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
pf_flow *pf_factory(const char *fileName, const le_font *font, gs_guiSupport *guiSupport)
|
||||
{
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
le_int32 charCount;
|
||||
const UChar *text = uc_readFile(fileName, guiSupport, &charCount);
|
||||
pl_fontRuns *fontRuns;
|
||||
pf_flow *result = NULL;
|
||||
|
||||
if (text == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fontRuns = pl_openEmptyFontRuns(0);
|
||||
|
||||
pl_addFontRun(fontRuns, font, charCount);
|
||||
|
||||
result = pf_create(text, charCount, fontRuns, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
pf_close(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pl_closeFontRuns(fontRuns);
|
||||
|
||||
DELETE_ARRAY(text);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
33
icu4c/source/samples/layout/pflow.h
Normal file
33
icu4c/source/samples/layout/pflow.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PFLOW_H
|
||||
#define __PFLOW_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "layout/LETypes.h"
|
||||
|
||||
#include "layout/plruns.h"
|
||||
#include "layout/playout.h"
|
||||
|
||||
#include "gsupport.h"
|
||||
#include "rsurface.h"
|
||||
|
||||
typedef void pf_flow;
|
||||
|
||||
pf_flow *pf_create(const LEUnicode chars[], le_int32 charCount, const pl_fontRuns *fontRuns, LEErrorCode *status);
|
||||
|
||||
void pf_close(pf_flow *flow);
|
||||
|
||||
le_int32 pf_getAscent(pf_flow *flow);
|
||||
le_int32 pf_getLineHeight(pf_flow *flow);
|
||||
le_int32 pf_getLineCount(pf_flow *flow);
|
||||
void pf_breakLines(pf_flow *flow, le_int32 width, le_int32 height);
|
||||
void pf_draw(pf_flow *flow, rs_surface *surface, le_int32 firstLine, le_int32 lastLine);
|
||||
|
||||
pf_flow *pf_factory(const char *fileName, const le_font *font, gs_guiSupport *guiSupport);
|
||||
|
||||
#endif
|
24
icu4c/source/samples/layout/rsurface.cpp
Normal file
24
icu4c/source/samples/layout/rsurface.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "loengine.h"
|
||||
#include "rsurface.h"
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "RenderingSurface.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
void rs_drawGlyphs(rs_surface *surface, const le_font *font, const LEGlyphID *glyphs, le_int32 count,
|
||||
const float *positions, le_int32 x, le_int32 y, le_int32 width, le_int32 height)
|
||||
{
|
||||
RenderingSurface *rs = (RenderingSurface *) surface;
|
||||
|
||||
rs->drawGlyphs((const LEFontInstance *) font, glyphs, count, positions, x, y, width, height);
|
||||
}
|
||||
|
||||
U_CDECL_END
|
21
icu4c/source/samples/layout/rsurface.h
Normal file
21
icu4c/source/samples/layout/rsurface.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RSURFACE_H
|
||||
#define __RSURFACE_H
|
||||
|
||||
#include "loengine.h"
|
||||
|
||||
typedef void rs_surface;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
void rs_drawGlyphs(rs_surface *surface, const le_font *font, const LEGlyphID *glyphs, le_int32 count,
|
||||
const float *positions, le_int32 x, le_int32 y, le_int32 width, le_int32 height);
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
#endif
|
20
icu4c/source/samples/layout/ucreader.cpp
Normal file
20
icu4c/source/samples/layout/ucreader.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#include "ucreader.h"
|
||||
#include "gsupport.h"
|
||||
#include "UnicodeReader.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
const UChar *uc_readFile(const char *fileName, gs_guiSupport *guiSupport, int32_t *charCount)
|
||||
{
|
||||
return UnicodeReader::readFile(fileName, (GUISupport *) guiSupport, *charCount);
|
||||
}
|
||||
|
||||
U_CDECL_END
|
19
icu4c/source/samples/layout/ucreader.h
Normal file
19
icu4c/source/samples/layout/ucreader.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __UCREADER_H
|
||||
#define __UCREADER_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "gsupport.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
const UChar *uc_readFile(const char *fileName, gs_guiSupport *guiSupport, int32_t *charCount);
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
## Makefile.in for ICU - test/letest
|
||||
## Copyright (c) 2001-2006, International Business Machines Corporation and
|
||||
## Copyright (c) 2001-2007, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
|
||||
## Source directory information
|
||||
@ -20,8 +20,8 @@ subdir = test/letest
|
||||
CLEANFILES = *~ $(DEPS)
|
||||
|
||||
## Target information
|
||||
TESTTARGET = letest
|
||||
GENTARGET = gendata
|
||||
TESTTARGET = letest
|
||||
GENTARGET = gendata
|
||||
|
||||
BUILDDIR := $(CURR_SRCCODE_FULL_DIR)/../../
|
||||
# Simplify the path for Unix
|
||||
@ -41,6 +41,7 @@ LIBS = $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) $(LIBCTESTFW) $(LIBICUTOOLUTIL) @LI
|
||||
|
||||
COMMONOBJECTS = letsutil.o cmaps.o FontTableCache.o SimpleFontInstance.o PortableFontInstance.o
|
||||
TESTOBJECTS = letest.o
|
||||
CTESTOBJECTS = cfonts.o xmlreader.o cletest.o
|
||||
GENOBJECTS = gendata.o
|
||||
|
||||
OBJECTS = $(COMMONOBJECTS) $(TESTOBJECTS) $(GENOBJECTS)
|
||||
@ -70,7 +71,7 @@ dist-local:
|
||||
|
||||
clean-local:
|
||||
test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
|
||||
$(RMV) $(OBJECTS) $(TARGET)
|
||||
$(RMV) $(COMMONOBJECTS) $(TESTOBJECTS) $(CTESTOBJECTS) $(GENOBJECTS) $(TARGET)
|
||||
|
||||
distclean-local: clean-local
|
||||
$(RMV) Makefile
|
||||
@ -82,7 +83,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(TESTTARGET) : $(COMMONOBJECTS) $(TESTOBJECTS)
|
||||
$(TESTTARGET) : $(COMMONOBJECTS) $(TESTOBJECTS) $(CTESTOBJECTS)
|
||||
$(LINK.cc) -o $@ $^ $(LIBS)
|
||||
$(POST_BUILD_STEP)
|
||||
|
||||
|
55
icu4c/source/test/letest/cfonts.cpp
Normal file
55
icu4c/source/test/letest/cfonts.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
#include "PortableFontInstance.h"
|
||||
#include "SimpleFontInstance.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
le_font *le_portableFontOpen(const char *fileName,
|
||||
float pointSize,
|
||||
LEErrorCode *status)
|
||||
{
|
||||
return (le_font *) new PortableFontInstance(fileName, pointSize, *status);
|
||||
}
|
||||
|
||||
le_font *le_simpleFontOpen(float pointSize,
|
||||
LEErrorCode *status)
|
||||
{
|
||||
return (le_font *) new SimpleFontInstance(pointSize, *status);
|
||||
}
|
||||
|
||||
void le_fontClose(le_font *font)
|
||||
{
|
||||
LEFontInstance *fontInstance = (LEFontInstance *) font;
|
||||
|
||||
delete fontInstance;
|
||||
}
|
||||
|
||||
const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
return pfi->getNameString(nameID, platform, encoding, language);
|
||||
}
|
||||
|
||||
void le_deleteNameString(le_font *font, const char *name)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
pfi->deleteNameString(name);
|
||||
}
|
||||
|
||||
le_uint32 le_getFontChecksum(le_font *font)
|
||||
{
|
||||
PortableFontInstance *pfi = (PortableFontInstance *) font;
|
||||
|
||||
return pfi->getFontChecksum();
|
||||
}
|
||||
|
||||
U_CDECL_END
|
28
icu4c/source/test/letest/cfonts.h
Normal file
28
icu4c/source/test/letest/cfonts.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CFONTS_H
|
||||
#define __CFONTS_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "loengine.h"
|
||||
|
||||
le_font *le_portableFontOpen(const char *fileName,
|
||||
float pointSize,
|
||||
LEErrorCode *status);
|
||||
|
||||
le_font *le_simpleFontOpen(float pointSize,
|
||||
LEErrorCode *status);
|
||||
|
||||
void le_fontClose(le_font *font);
|
||||
|
||||
const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language);
|
||||
|
||||
void le_deleteNameString(le_font *font, const char *name);
|
||||
|
||||
le_uint32 le_getFontChecksum(le_font *font);
|
||||
|
||||
#endif
|
489
icu4c/source/test/letest/cletest.c
Normal file
489
icu4c/source/test/letest/cletest.c
Normal file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ubidi.h"
|
||||
#include "unicode/uscript.h"
|
||||
#include "unicode/ctest.h"
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LEScripts.h"
|
||||
#include "loengine.h"
|
||||
|
||||
#include "cfonts.h"
|
||||
|
||||
#include "letest.h"
|
||||
|
||||
#include "sfnt.h"
|
||||
#include "xmlreader.h"
|
||||
#include "putilimp.h" /* for U_FILE_SEP_STRING */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CH_COMMA 0x002C
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static void U_CALLCONV ParamTest(void)
|
||||
{
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
le_font *font = le_simpleFontOpen(12, &status);
|
||||
le_engine *engine = le_create(font, arabScriptCode, -1, 0, &status);
|
||||
LEGlyphID *glyphs = NULL;
|
||||
le_int32 *indices = NULL;
|
||||
float *positions = NULL;
|
||||
le_int32 glyphCount = 0;
|
||||
|
||||
float x = 0.0, y = 0.0;
|
||||
LEUnicode chars[] = {
|
||||
0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, /* "English " */
|
||||
0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, /* MEM ALIF KAF NOON TEH WAW SHEEN */
|
||||
0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E /* " text." */
|
||||
};
|
||||
|
||||
|
||||
glyphCount = le_getGlyphCount(engine, &status);
|
||||
if (glyphCount != 0) {
|
||||
log_err("Calling getGlyphCount() on an empty layout returned %d.\n", glyphCount);
|
||||
}
|
||||
|
||||
glyphs = NEW_ARRAY(LEGlyphID, glyphCount + 10);
|
||||
indices = NEW_ARRAY(le_int32, glyphCount + 10);
|
||||
positions = NEW_ARRAY(float, glyphCount + 10);
|
||||
|
||||
le_getGlyphs(engine, NULL, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling getGlyphs(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getGlyphs(engine, glyphs, &status);
|
||||
|
||||
if (status != LE_NO_LAYOUT_ERROR) {
|
||||
log_err("Calling getGlyphs(glyphs, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getCharIndices(engine, NULL, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling getCharIndices(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getCharIndices(engine, indices, &status);
|
||||
|
||||
if (status != LE_NO_LAYOUT_ERROR) {
|
||||
log_err("Calling getCharIndices(indices, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getCharIndicesWithBase(engine, NULL, 1024, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling getCharIndices(NULL, 1024, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getCharIndicesWithBase(engine, indices, 1024, &status);
|
||||
|
||||
if (status != LE_NO_LAYOUT_ERROR) {
|
||||
log_err("Calling getCharIndices(indices, 1024, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getGlyphPositions(engine, NULL, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling getGlyphPositions(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getGlyphPositions(engine, positions, &status);
|
||||
|
||||
if (status != LE_NO_LAYOUT_ERROR) {
|
||||
log_err("Calling getGlyphPositions(positions, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
|
||||
}
|
||||
|
||||
DELETE_ARRAY(positions);
|
||||
DELETE_ARRAY(indices);
|
||||
DELETE_ARRAY(glyphs);
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, NULL, 0, 0, 0, FALSE, 0.0, 0.0, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling layoutChars(NULL, 0, 0, 0, FALSE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, chars, -1, 6, 20, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling layoutChars(chars, -1, 6, 20, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, chars, 8, -1, 20, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling layoutChars(chars, 8, -1, 20, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, chars, 8, 6, -1, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling layoutChars((chars, 8, 6, -1, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, chars, 8, 6, 10, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
|
||||
log_err("Calling layoutChars(chars, 8, 6, 10, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
glyphCount = le_layoutChars(engine, chars, 8, 6, 20, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("Calling layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status) failed.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
le_getGlyphPosition(engine, -1, &x, &y, &status);
|
||||
|
||||
if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) {
|
||||
log_err("Calling getGlyphPosition(-1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n");
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getGlyphPosition(engine, glyphCount + 1, &x, &y, &status);
|
||||
|
||||
if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) {
|
||||
log_err("Calling getGlyphPosition(glyphCount + 1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n");
|
||||
}
|
||||
|
||||
bail:
|
||||
le_close(engine);
|
||||
le_fontClose(font);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static void U_CALLCONV FactoryTest(void)
|
||||
{
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
le_font *font = le_simpleFontOpen(12, &status);
|
||||
le_engine *engine = NULL;
|
||||
le_int32 scriptCode;
|
||||
|
||||
for(scriptCode = 0; scriptCode < scriptCodeCount; scriptCode += 1) {
|
||||
status = LE_NO_ERROR;
|
||||
engine = le_create(font, scriptCode, -1, 0, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("Could not create a LayoutEngine for script \'%s\'.\n", uscript_getShortName((UScriptCode)scriptCode));
|
||||
}
|
||||
|
||||
le_close(engine);
|
||||
}
|
||||
|
||||
le_fontClose(font);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static void U_CALLCONV AccessTest(void)
|
||||
{
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
le_font *font = le_simpleFontOpen(12, &status);
|
||||
le_engine *engine =le_create(font, arabScriptCode, -1, 0, &status);
|
||||
le_int32 glyphCount;
|
||||
LEGlyphID glyphs[6];
|
||||
le_int32 biasedIndices[6], indices[6], glyph;
|
||||
float positions[6 * 2 + 2];
|
||||
LEUnicode chars[] = {
|
||||
0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, /* "English " */
|
||||
0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, /* MEM ALIF KAF NOON TEH WAW SHEEN */
|
||||
0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E /* " text." */
|
||||
};
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("Could not create LayoutEngine.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
glyphCount = le_layoutChars(engine, chars, 8, 6, 20, TRUE, 0.0, 0.0, &status);
|
||||
|
||||
if (LE_FAILURE(status) || glyphCount != 6) {
|
||||
log_err("layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status) failed.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
le_getGlyphs(engine, glyphs, &status);
|
||||
le_getCharIndices(engine, indices, &status);
|
||||
le_getGlyphPositions(engine, positions, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("Could not get glyph, indices and position arrays.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
le_getCharIndicesWithBase(engine, biasedIndices, 1024, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("getCharIndices(biasedIndices, 1024, status) failed.\n");
|
||||
} else {
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
if (biasedIndices[glyph] != (indices[glyph] + 1024)) {
|
||||
log_err("biasedIndices[%d] != indices[%d] + 1024: %8X, %8X\n",
|
||||
glyph, glyph, biasedIndices[glyph], indices[glyph]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status = LE_NO_ERROR;
|
||||
for (glyph = 0; glyph <= glyphCount; glyph += 1) {
|
||||
float x = 0.0, y = 0.0;
|
||||
|
||||
le_getGlyphPosition(engine, glyph, &x, &y, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("getGlyphPosition(%d, x, y, status) failed.\n", glyph);
|
||||
break;
|
||||
}
|
||||
|
||||
if (x != positions[glyph*2] || y != positions[glyph*2 + 1]) {
|
||||
log_err("getGlyphPosition(%d, x, y, status) returned bad position: (%f, %f) != (%f, %f)\n",
|
||||
glyph, x, y, positions[glyph*2], positions[glyph*2 + 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
le_close(engine);
|
||||
le_fontClose(font);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
static le_bool compareResults(const char *testID, TestResult *expected, TestResult *actual)
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
/* NOTE: we'll stop on the first failure 'cause once there's one error, it may cascade... */
|
||||
if (actual->glyphCount != expected->glyphCount) {
|
||||
log_err("Test %s: incorrect glyph count: exptected %d, got %d\n",
|
||||
testID, expected->glyphCount, actual->glyphCount);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < actual->glyphCount; i += 1) {
|
||||
if (actual->glyphs[i] != expected->glyphs[i]) {
|
||||
log_err("Test %s: incorrect id for glyph %d: expected %4X, got %4X\n",
|
||||
testID, i, expected->glyphs[i], actual->glyphs[i]);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < actual->glyphCount; i += 1) {
|
||||
if (actual->indices[i] != expected->indices[i]) {
|
||||
log_err("Test %s: incorrect index for glyph %d: expected %8X, got %8X\n",
|
||||
testID, i, expected->indices[i], actual->indices[i]);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= actual->glyphCount; i += 1) {
|
||||
double xError = uprv_fabs(actual->positions[i * 2] - expected->positions[i * 2]);
|
||||
double yError = uprv_fabs(actual->positions[i * 2 + 1] - expected->positions[i * 2 + 1]);
|
||||
|
||||
if (xError > 0.0001) {
|
||||
log_err("Test %s: incorrect x position for glyph %d: expected %f, got %f\n",
|
||||
testID, i, expected->positions[i * 2], actual->positions[i * 2]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (yError < 0) {
|
||||
yError = -yError;
|
||||
}
|
||||
|
||||
if (yError > 0.0001) {
|
||||
log_err("Test %s: incorrect y position for glyph %d: expected %f, got %f\n",
|
||||
testID, i, expected->positions[i * 2 + 1], actual->positions[i * 2 + 1]);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void checkFontVersion(le_font *font, const char *testVersionString,
|
||||
le_uint32 testChecksum, const char *testID)
|
||||
{
|
||||
le_uint32 fontChecksum = le_getFontChecksum(font);
|
||||
|
||||
if (fontChecksum != testChecksum) {
|
||||
const char *fontVersionString = le_getNameString(font, NAME_VERSION_STRING,
|
||||
PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
|
||||
|
||||
log_info("Test %s: this may not be the same font used to generate the test data.\n", testID);
|
||||
log_info("Your font's version string is \"%s\"\n", fontVersionString);
|
||||
log_info("The expected version string is \"%s\"\n", testVersionString);
|
||||
log_info("If you see errors, they may be due to the version of the font you're using.\n");
|
||||
|
||||
le_deleteNameString(font, fontVersionString);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the path to icu/source/test/testdata/ */
|
||||
static const char *getSourceTestData() {
|
||||
#ifdef U_TOPSRCDIR
|
||||
const char *srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
|
||||
#else
|
||||
const char *srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
|
||||
FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r");
|
||||
|
||||
if (f != NULL) {
|
||||
/* We're in icu/source/test/letest/ */
|
||||
fclose(f);
|
||||
} else {
|
||||
/* We're in icu/source/test/letest/(Debug|Release) */
|
||||
srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
|
||||
}
|
||||
#endif
|
||||
|
||||
return srcDataDir;
|
||||
}
|
||||
|
||||
static const char *getPath(char buffer[2048], const char *filename) {
|
||||
const char *testDataDirectory = getSourceTestData();
|
||||
|
||||
strcpy(buffer, testDataDirectory);
|
||||
strcat(buffer, filename);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static le_font *openFont(const char *fontName, const char *checksum, const char *version, const char *testID)
|
||||
{
|
||||
char path[2048];
|
||||
le_font *font;
|
||||
LEErrorCode fontStatus = LE_NO_ERROR;
|
||||
|
||||
if (fontName != NULL) {
|
||||
font = le_portableFontOpen(getPath(path, fontName), 12, &fontStatus);
|
||||
|
||||
if (LE_FAILURE(fontStatus)) {
|
||||
log_info("Test %s: can't open font %s - test skipped.\n", testID, fontName);
|
||||
le_fontClose(font);
|
||||
return NULL;
|
||||
} else {
|
||||
le_uint32 cksum = 0;
|
||||
|
||||
sscanf(checksum, "%x", &cksum);
|
||||
|
||||
checkFontVersion(font, version, cksum, testID);
|
||||
}
|
||||
} else {
|
||||
font = le_simpleFontOpen(12, &fontStatus);
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static le_bool getRTL(const LEUnicode *text, le_int32 charCount)
|
||||
{
|
||||
UBiDiLevel paraLevel;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UBiDi *ubidi = ubidi_openSized(charCount, 0, &status);
|
||||
|
||||
ubidi_setPara(ubidi, text, charCount, UBIDI_DEFAULT_LTR, NULL, &status);
|
||||
paraLevel = ubidi_getParaLevel(ubidi);
|
||||
ubidi_close(ubidi);
|
||||
|
||||
return paraLevel & 1;
|
||||
}
|
||||
|
||||
static void doTestCase (const char *testID,
|
||||
const char *fontName,
|
||||
const char *fontVersion,
|
||||
const char *fontChecksum,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
const LEUnicode *text,
|
||||
le_int32 charCount,
|
||||
TestResult *expected)
|
||||
{
|
||||
LEErrorCode status = LE_NO_ERROR;
|
||||
le_engine *engine;
|
||||
le_font *font = openFont(fontName, fontChecksum, fontVersion, testID);
|
||||
le_int32 typoFlags = 3; /* kerning + ligatures */
|
||||
TestResult actual;
|
||||
|
||||
if (font == NULL) {
|
||||
/* error message already printed. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (fontName == NULL) {
|
||||
typoFlags |= 0x80000000L; /* use CharSubstitutionFilter... */
|
||||
}
|
||||
|
||||
engine = le_create(font, scriptCode, languageCode, typoFlags, &status);
|
||||
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("Test %s: could not create a LayoutEngine.\n", testID);
|
||||
goto free_expected;
|
||||
}
|
||||
|
||||
actual.glyphCount = le_layoutChars(engine, text, 0, charCount, charCount, getRTL(text, charCount), 0, 0, &status);
|
||||
|
||||
actual.glyphs = NEW_ARRAY(LEGlyphID, actual.glyphCount);
|
||||
actual.indices = NEW_ARRAY(le_int32, actual.glyphCount);
|
||||
actual.positions = NEW_ARRAY(float, actual.glyphCount * 2 + 2);
|
||||
|
||||
le_getGlyphs(engine, actual.glyphs, &status);
|
||||
le_getCharIndices(engine, actual.indices, &status);
|
||||
le_getGlyphPositions(engine, actual.positions, &status);
|
||||
|
||||
compareResults(testID, expected, &actual);
|
||||
|
||||
DELETE_ARRAY(actual.positions);
|
||||
DELETE_ARRAY(actual.indices);
|
||||
DELETE_ARRAY(actual.glyphs);
|
||||
|
||||
le_close(engine);
|
||||
|
||||
free_expected:
|
||||
le_fontClose(font);
|
||||
}
|
||||
|
||||
static void U_CALLCONV DataDrivenTest(void)
|
||||
{
|
||||
char path[2048];
|
||||
const char *testFilePath = getPath(path, "letest.xml");
|
||||
|
||||
readTestFile(testFilePath, doTestCase);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
20
icu4c/source/test/letest/cletest.sln
Normal file
20
icu4c/source/test/letest/cletest.sln
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cletest", "cletest.vcproj", "{798E3AE4-A984-43FF-8928-EACFF43F56AE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{798E3AE4-A984-43FF-8928-EACFF43F56AE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{798E3AE4-A984-43FF-8928-EACFF43F56AE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{798E3AE4-A984-43FF-8928-EACFF43F56AE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{798E3AE4-A984-43FF-8928-EACFF43F56AE}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
273
icu4c/source/test/letest/cletest.vcproj
Normal file
273
icu4c/source/test/letest/cletest.vcproj
Normal file
@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="cletest"
|
||||
ProjectGUID="{798E3AE4-A984-43FF-8928-EACFF43F56AE}"
|
||||
RootNamespace="cletest"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\include\layout;..\..\..\include;..\..\common;..\..\tools\ctestfw;..\..\tools\toolutil;..\..\layout"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="..\..\..\lib\icuucd.lib ..\..\..\lib\icuind.lib ..\..\..\lib\icutestd.lib ..\..\..\lib\icutud.lib ..\..\..\lib\iculed.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\..\include\layout;..\..\..\include;..\..\common;..\..\tools\ctestfw;..\..\tools\toolutil;..\..\layout"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="..\..\..\lib\icuuc.lib ..\..\..\lib\icuin.lib ..\..\..\lib\icutest.lib ..\..\..\lib\icutu.lib ..\..\..\lib\icule.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\cfonts.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cletest.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cmaps.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontObject.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontTableCache.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\letsutil.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PortableFontInstance.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SimpleFontInstance.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmlreader.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\cfonts.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cmaps.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontObject.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontTableCache.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\letest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\letsutil.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PortableFontInstance.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sfnt.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SimpleFontInstance.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmlreader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2006, International Business Machines
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -657,7 +657,7 @@ static void U_CALLCONV DataDrivenTest(void)
|
||||
expected.glyphCount = glyphCount;
|
||||
|
||||
if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) {
|
||||
log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n",
|
||||
log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n",
|
||||
id, charCount, glyphCount, indexCount, positionCount);
|
||||
goto free_expected;
|
||||
};
|
||||
@ -707,12 +707,14 @@ free_c_strings:
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
static void addAllTests(TestNode** root)
|
||||
static void addAllTests(TestNode **root)
|
||||
{
|
||||
addTest(root, &ParamTest, "api/ParameterTest");
|
||||
addTest(root, &FactoryTest, "api/FactoryTest");
|
||||
addTest(root, &AccessTest, "layout/AccessTest");
|
||||
addTest(root, &DataDrivenTest, "layout/DataDrivenTest");
|
||||
|
||||
addCTests(root);
|
||||
}
|
||||
|
||||
/* returns the path to icu/source/data/out */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define __LETEST_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "unicode/ctest.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -38,4 +39,11 @@ struct TestResult
|
||||
le_int32 *indices;
|
||||
float *positions;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct TestResult TestResult;
|
||||
#endif
|
||||
|
||||
U_CFUNC void addCTests(TestNode **root);
|
||||
|
||||
#endif
|
||||
|
@ -201,6 +201,14 @@
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\cfonts.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cletest.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cmaps.cpp"
|
||||
>
|
||||
@ -225,11 +233,19 @@
|
||||
RelativePath=".\SimpleFontInstance.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmlreader.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\cfonts.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cmaps.h"
|
||||
>
|
||||
@ -258,6 +274,10 @@
|
||||
RelativePath=".\SimpleFontInstance.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmlreader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
@ -24,6 +24,10 @@ struct DirectoryEntry
|
||||
le_uint32 length;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct DirectoryEntry DirectoryEntry;
|
||||
#endif
|
||||
|
||||
struct SFNTDirectory
|
||||
{
|
||||
le_uint32 scalerType;
|
||||
@ -34,6 +38,10 @@ struct SFNTDirectory
|
||||
DirectoryEntry tableDirectory[ANY_NUMBER];
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct SFNTDirectory SFNTDirectory;
|
||||
#endif
|
||||
|
||||
|
||||
struct CMAPEncodingSubtableHeader
|
||||
{
|
||||
@ -42,6 +50,10 @@ struct CMAPEncodingSubtableHeader
|
||||
le_uint32 encodingOffset;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPEncodingSubtableHeader CMAPEncodingSubtableHeader;
|
||||
#endif
|
||||
|
||||
struct CMAPTable
|
||||
{
|
||||
le_uint16 version;
|
||||
@ -49,6 +61,10 @@ struct CMAPTable
|
||||
CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER];
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPTable CMAPTable;
|
||||
#endif
|
||||
|
||||
struct CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 format;
|
||||
@ -56,10 +72,25 @@ struct CMAPEncodingSubtable
|
||||
le_uint16 language;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPEncodingSubtable CMAPEncodingSubtable;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat0Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint8 glyphIndexArray[256];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat0Encoding
|
||||
{
|
||||
CMAPEncodingSubtable base;
|
||||
|
||||
le_uint8 glyphIndexArray[256];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat0Encoding CMAPFormat0Encoding;
|
||||
#endif
|
||||
|
||||
struct CMAPFormat2Subheader
|
||||
{
|
||||
@ -69,12 +100,29 @@ struct CMAPFormat2Subheader
|
||||
le_uint16 idRangeOffset;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPFormat2Subheader CMAPFormat2Subheader;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat2Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 subHeadKeys[256];
|
||||
CMAPFormat2Subheader subheaders[ANY_NUMBER];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat2Encoding
|
||||
{
|
||||
CMAPEncodingSubtable base;
|
||||
|
||||
le_uint16 subHeadKeys[256];
|
||||
CMAPFormat2Subheader subheaders[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat2Encoding CMAPFormat2Encoding;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat4Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 segCountX2;
|
||||
@ -82,19 +130,55 @@ struct CMAPFormat4Encoding : CMAPEncodingSubtable
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
le_uint16 endCodes[ANY_NUMBER];
|
||||
/*
|
||||
le_uint16 reservedPad;
|
||||
le_uint16 startCodes[ANY_NUMBER];
|
||||
le_uint16 idDelta[ANY_NUMBER];
|
||||
le_uint16 idRangeOffset[ANY_NUMBER];
|
||||
le_uint16 glyphIndexArray[ANY_NUMBER];
|
||||
*/
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat4Encoding
|
||||
{
|
||||
CMAPEncodingSubtable base;
|
||||
|
||||
le_uint16 segCountX2;
|
||||
le_uint16 searchRange;
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
le_uint16 endCodes[ANY_NUMBER];
|
||||
/*
|
||||
// le_uint16 reservedPad;
|
||||
// le_uint16 startCodes[ANY_NUMBER];
|
||||
// le_uint16 idDelta[ANY_NUMBER];
|
||||
// le_uint16 idRangeOffset[ANY_NUMBER];
|
||||
// le_uint16 glyphIndexArray[ANY_NUMBER];
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat4Encoding CMAPFormat4Encoding;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat6Encoding : CMAPEncodingSubtable
|
||||
{
|
||||
le_uint16 firstCode;
|
||||
le_uint16 entryCount;
|
||||
le_uint16 glyphIndexArray[ANY_NUMBER];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat6Encoding
|
||||
{
|
||||
CMAPEncodingSubtable base;
|
||||
|
||||
le_uint16 firstCode;
|
||||
le_uint16 entryCount;
|
||||
le_uint16 glyphIndexArray[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat6Encoding CMAPFormat6Encoding;
|
||||
#endif
|
||||
|
||||
struct CMAPEncodingSubtable32
|
||||
{
|
||||
@ -103,6 +187,10 @@ struct CMAPEncodingSubtable32
|
||||
le_uint32 language;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPEncodingSubtable32 CMAPEncodingSubtable32;
|
||||
#endif
|
||||
|
||||
struct CMAPGroup
|
||||
{
|
||||
le_uint32 startCharCode;
|
||||
@ -110,25 +198,67 @@ struct CMAPGroup
|
||||
le_uint32 startGlyphCode;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct CMAPGroup CMAPGroup;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat8Encoding : CMAPEncodingSubtable32
|
||||
{
|
||||
le_uint32 is32[65536/32];
|
||||
le_uint32 nGroups;
|
||||
CMAPGroup groups[ANY_NUMBER];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat8Encoding
|
||||
{
|
||||
CMAPEncodingSubtable32 base;
|
||||
|
||||
le_uint32 is32[65536/32];
|
||||
le_uint32 nGroups;
|
||||
CMAPGroup groups[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat8Encoding CMAPFormat8Encoding;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat10Encoding : CMAPEncodingSubtable32
|
||||
{
|
||||
le_uint32 startCharCode;
|
||||
le_uint32 numCharCodes;
|
||||
le_uint16 glyphs[ANY_NUMBER];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat10Encoding
|
||||
{
|
||||
CMAPEncodingSubtable32 base;
|
||||
|
||||
le_uint32 startCharCode;
|
||||
le_uint32 numCharCodes;
|
||||
le_uint16 glyphs[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat10Encoding CMAPFormat10Encoding;
|
||||
#endif
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
struct CMAPFormat12Encoding : CMAPEncodingSubtable32
|
||||
{
|
||||
le_uint32 nGroups;
|
||||
CMAPGroup groups[ANY_NUMBER];
|
||||
};
|
||||
#else
|
||||
struct CMAPFormat12Encoding
|
||||
{
|
||||
CMAPEncodingSubtable32 base;
|
||||
|
||||
le_uint32 nGroups;
|
||||
CMAPGroup groups[ANY_NUMBER];
|
||||
};
|
||||
|
||||
typedef struct CMAPFormat12Encoding CMAPFormat12Encoding;
|
||||
#endif
|
||||
|
||||
typedef le_int32 fixed;
|
||||
|
||||
@ -138,6 +268,10 @@ struct BigDate
|
||||
le_uint32 ad;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct BigDate BigDate;
|
||||
#endif
|
||||
|
||||
struct HEADTable
|
||||
{
|
||||
fixed version;
|
||||
@ -158,6 +292,10 @@ struct HEADTable
|
||||
le_int16 glyphDataFormat;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct HEADTable HEADTable;
|
||||
#endif
|
||||
|
||||
struct MAXPTable
|
||||
{
|
||||
fixed version;
|
||||
@ -177,6 +315,10 @@ struct MAXPTable
|
||||
le_uint16 maxComponentDepth;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct MAXPTable MAXPTable;
|
||||
#endif
|
||||
|
||||
struct HHEATable
|
||||
{
|
||||
fixed version;
|
||||
@ -198,18 +340,30 @@ struct HHEATable
|
||||
le_uint16 numOfLongHorMetrics;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct HHEATable HHEATable;
|
||||
#endif
|
||||
|
||||
struct LongHorMetric
|
||||
{
|
||||
le_uint16 advanceWidth;
|
||||
le_int16 leftSideBearing;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct LongHorMetric LongHorMetric;
|
||||
#endif
|
||||
|
||||
struct HMTXTable
|
||||
{
|
||||
LongHorMetric hMetrics[ANY_NUMBER]; // ANY_NUMBER = numOfLongHorMetrics from hhea table
|
||||
// le_int16 leftSideBearing[ANY_NUMBER]; // ANY_NUMBER = numGlyphs - numOfLongHorMetrics
|
||||
LongHorMetric hMetrics[ANY_NUMBER]; /* ANY_NUMBER = numOfLongHorMetrics from hhea table */
|
||||
/* le_int16 leftSideBearing[ANY_NUMBER]; ANY_NUMBER = numGlyphs - numOfLongHorMetrics */
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct HMTXTable HMTXTable;
|
||||
#endif
|
||||
|
||||
enum PlatformID
|
||||
{
|
||||
PLATFORM_UNICODE = 0,
|
||||
@ -264,6 +418,10 @@ struct NameRecord
|
||||
le_uint16 offset;
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct NameRecord NameRecord;
|
||||
#endif
|
||||
|
||||
struct NAMETable
|
||||
{
|
||||
le_uint16 version;
|
||||
@ -272,5 +430,9 @@ struct NAMETable
|
||||
NameRecord nameRecords[ANY_NUMBER];
|
||||
};
|
||||
|
||||
#ifndef XP_CPLUSPLUS
|
||||
typedef struct NAMETable NAMETable;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
259
icu4c/source/test/letest/xmlreader.cpp
Normal file
259
icu4c/source/test/letest/xmlreader.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "unicode/uchar.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/uscript.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/ctest.h"
|
||||
|
||||
#include "layout/LETypes.h"
|
||||
#include "layout/LEScripts.h"
|
||||
|
||||
#include "letsutil.h"
|
||||
#include "letest.h"
|
||||
|
||||
#include "xmlreader.h"
|
||||
|
||||
#include "xmlparser.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//U_NAMESPACE_USE
|
||||
|
||||
#define CH_COMMA 0x002C
|
||||
|
||||
static le_uint32 *getHexArray(const UnicodeString &numbers, int32_t &arraySize)
|
||||
{
|
||||
int32_t offset = -1;
|
||||
|
||||
arraySize = 1;
|
||||
while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
|
||||
arraySize += 1;
|
||||
}
|
||||
|
||||
le_uint32 *array = NEW_ARRAY(le_uint32, arraySize);
|
||||
char number[16];
|
||||
le_int32 count = 0;
|
||||
le_int32 start = 0, end = 0;
|
||||
le_int32 len = 0;
|
||||
|
||||
// trim leading whitespace
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
start = end + 1;
|
||||
|
||||
sscanf(number, "%x", &array[count++]);
|
||||
|
||||
// trim whitespace following the comma
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// trim trailing whitespace
|
||||
end = numbers.length();
|
||||
while(u_isUWhiteSpace(numbers[end - 1])) {
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
sscanf(number, "%x", &array[count]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static float *getFloatArray(const UnicodeString &numbers, int32_t &arraySize)
|
||||
{
|
||||
int32_t offset = -1;
|
||||
|
||||
arraySize = 1;
|
||||
while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
|
||||
arraySize += 1;
|
||||
}
|
||||
|
||||
float *array = NEW_ARRAY(float, arraySize);
|
||||
char number[32];
|
||||
le_int32 count = 0;
|
||||
le_int32 start = 0, end = 0;
|
||||
le_int32 len = 0;
|
||||
|
||||
// trim leading whitespace
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
start = end + 1;
|
||||
|
||||
sscanf(number, "%f", &array[count++]);
|
||||
|
||||
// trim whiteapce following the comma
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
}
|
||||
|
||||
while(u_isUWhiteSpace(numbers[start])) {
|
||||
start += 1;
|
||||
}
|
||||
|
||||
// trim trailing whitespace
|
||||
end = numbers.length();
|
||||
while(u_isUWhiteSpace(numbers[end - 1])) {
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
|
||||
number[len] = '\0';
|
||||
sscanf(number, "%f", &array[count]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
U_CDECL_BEGIN
|
||||
void readTestFile(const char *testFilePath, TestCaseCallback callback)
|
||||
{
|
||||
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UXMLParser *parser = UXMLParser::createParser(status);
|
||||
UXMLElement *root = parser->parseFile(testFilePath, status);
|
||||
|
||||
if (root == NULL) {
|
||||
log_err("Could not open the test data file: %s\n", testFilePath);
|
||||
delete parser;
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case");
|
||||
UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text");
|
||||
UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font");
|
||||
UnicodeString result_glyphs = UNICODE_STRING_SIMPLE("result-glyphs");
|
||||
UnicodeString result_indices = UNICODE_STRING_SIMPLE("result-indices");
|
||||
UnicodeString result_positions = UNICODE_STRING_SIMPLE("result-positions");
|
||||
|
||||
// test-case attributes
|
||||
UnicodeString id_attr = UNICODE_STRING_SIMPLE("id");
|
||||
UnicodeString script_attr = UNICODE_STRING_SIMPLE("script");
|
||||
UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang");
|
||||
|
||||
// test-font attributes
|
||||
UnicodeString name_attr = UNICODE_STRING_SIMPLE("name");
|
||||
UnicodeString ver_attr = UNICODE_STRING_SIMPLE("version");
|
||||
UnicodeString cksum_attr = UNICODE_STRING_SIMPLE("checksum");
|
||||
|
||||
const UXMLElement *testCase;
|
||||
int32_t tc = 0;
|
||||
|
||||
while((testCase = root->nextChildElement(tc)) != NULL) {
|
||||
if (testCase->getTagName().compare(test_case) == 0) {
|
||||
char *id = getCString(testCase->getAttribute(id_attr));
|
||||
char *script = getCString(testCase->getAttribute(script_attr));
|
||||
char *lang = getCString(testCase->getAttribute(lang_attr));
|
||||
char *fontName = NULL;
|
||||
char *fontVer = NULL;
|
||||
char *fontCksum = NULL;
|
||||
const UXMLElement *element;
|
||||
int32_t ec = 0;
|
||||
int32_t charCount = 0;
|
||||
int32_t typoFlags = 3; // kerning + ligatures...
|
||||
UScriptCode scriptCode;
|
||||
le_int32 languageCode = -1;
|
||||
UnicodeString text, glyphs, indices, positions;
|
||||
int32_t glyphCount = 0, indexCount = 0, positionCount = 0;
|
||||
TestResult expected = {0, NULL, NULL, NULL};
|
||||
|
||||
uscript_getCode(script, &scriptCode, 1, &status);
|
||||
if (LE_FAILURE(status)) {
|
||||
log_err("invalid script name: %s.\n", script);
|
||||
goto free_c_strings;
|
||||
}
|
||||
|
||||
if (lang != NULL) {
|
||||
languageCode = getLanguageCode(lang);
|
||||
|
||||
if (languageCode < 0) {
|
||||
log_err("invalid language name: %s.\n", lang);
|
||||
goto free_c_strings;
|
||||
}
|
||||
}
|
||||
|
||||
while((element = testCase->nextChildElement(ec)) != NULL) {
|
||||
UnicodeString tag = element->getTagName();
|
||||
|
||||
// TODO: make sure that each element is only used once.
|
||||
if (tag.compare(test_font) == 0) {
|
||||
fontName = getCString(element->getAttribute(name_attr));
|
||||
fontVer = getCString(element->getAttribute(ver_attr));
|
||||
fontCksum = getCString(element->getAttribute(cksum_attr));
|
||||
|
||||
} else if (tag.compare(test_text) == 0) {
|
||||
text = element->getText(TRUE);
|
||||
charCount = text.length();
|
||||
} else if (tag.compare(result_glyphs) == 0) {
|
||||
glyphs = element->getText(TRUE);
|
||||
} else if (tag.compare(result_indices) == 0) {
|
||||
indices = element->getText(TRUE);
|
||||
} else if (tag.compare(result_positions) == 0) {
|
||||
positions = element->getText(TRUE);
|
||||
} else {
|
||||
// an unknown tag...
|
||||
char *cTag = getCString(&tag);
|
||||
|
||||
log_info("Test %s: unknown element with tag \"%s\"\n", id, cTag);
|
||||
freeCString(cTag);
|
||||
}
|
||||
}
|
||||
|
||||
expected.glyphs = (LEGlyphID *) getHexArray(glyphs, glyphCount);
|
||||
expected.indices = (le_int32 *) getHexArray(indices, indexCount);
|
||||
expected.positions = getFloatArray(positions, positionCount);
|
||||
|
||||
expected.glyphCount = glyphCount;
|
||||
|
||||
if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) {
|
||||
log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n",
|
||||
id, charCount, glyphCount, indexCount, positionCount);
|
||||
goto free_expected;
|
||||
};
|
||||
|
||||
(*callback)(id, fontName, fontVer, fontCksum, scriptCode, languageCode, text.getBuffer(), charCount, &expected);
|
||||
|
||||
free_expected:
|
||||
DELETE_ARRAY(expected.positions);
|
||||
DELETE_ARRAY(expected.indices);
|
||||
DELETE_ARRAY(expected.glyphs);
|
||||
|
||||
free_c_strings:
|
||||
freeCString(fontCksum);
|
||||
freeCString(fontVer);
|
||||
freeCString(fontName);
|
||||
freeCString(lang);
|
||||
freeCString(script);
|
||||
freeCString(id);
|
||||
}
|
||||
}
|
||||
|
||||
delete root;
|
||||
delete parser;
|
||||
#endif
|
||||
}
|
||||
U_CDECL_END
|
25
icu4c/source/test/letest/xmlreader.h
Normal file
25
icu4c/source/test/letest/xmlreader.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XMLREADER_H
|
||||
#define __XMLREADER_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "letest.h"
|
||||
|
||||
typedef void (*TestCaseCallback) (const char *testID,
|
||||
const char *fontName,
|
||||
const char *fontVersion,
|
||||
const char *fontChecksum,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
const LEUnicode *text,
|
||||
le_int32 charCount,
|
||||
TestResult *expected);
|
||||
|
||||
U_CAPI void readTestFile(const char *testFilePath, TestCaseCallback callback);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user