summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite/src/segment/GrCharStream.h
blob: 892435d376eed7d9259a98fecf5d2debb6f4dbc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*--------------------------------------------------------------------*//*:Ignore this sentence.
Copyright (C) 1999 - 2008 SIL International. All rights reserved.

Distributable under the terms of either the Common Public License or the
GNU Lesser General Public License, as specified in the LICENSING.txt file.

File: GrCharStream.h
Responsibility: Sharon Correll
Last reviewed: Not yet.

Description:
	

----------------------------------------------------------------------------------------------*/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef GR_CHARSTREAM_INCLUDED
#define GR_CHARSTREAM_INCLUDED

//:End Ignore

namespace gr
{

/*----------------------------------------------------------------------------------------------
	Makes a stream out of a text string that is serving as input to the process.
	
	Hungarian: chstrm
----------------------------------------------------------------------------------------------*/
class GrCharStream
{
public:
	//	Constructor and destructor:
	GrCharStream(ITextSource * pgts, int ichrMin, int ichrLim,
		bool fStartLine, bool fEndLine);

	~GrCharStream()
	{
		if (m_cchlRunMax >= 0)
			delete[] m_prgchlRunText;
	}

	//	Getters:
	ITextSource * TextSrc()		{ return m_pgts; }
	int Min()					{ return m_ichrMin; }
	int Pos()					{ return m_ichrPos; }
	int Lim()					{ return m_ichrLim; }
	bool StartLine()			{ return m_fStartLine; }
	bool EndLine()				{ return m_fEndLine; }

	//	offset from the beginning of the segment
	int SegOffset()				{ return m_ichrPos - m_ichrMin; }
	int SegOffset(int ichr)		{ return ichr - m_ichrMin; }

	bool AtEnd()
	{
		return (m_ichrPos >= m_ichrLim);
	}

	//	The input string is empty.
	bool IsEmpty()
	{
		return (m_ichrLim - m_ichrMin == 0);
	}

	//	When we are restarting in order to create a segment other than the first,
	//	back up the position in the stream slightly in order to reprocess a few characters
	//	before the line-break.
	void Backup(int cchrToReprocess)
	{
		Assert(m_ichrPos >= cchrToReprocess);
		m_ichrPos -= cchrToReprocess;
		m_ichrRunOffset = kPosInfinity;
		m_cchrBackedUp = cchrToReprocess;
	}

	//	When we found a hard-break in the input stream, we need to put it back, and since
	//	we're done, we set the end of the stream to that position.
	void HitHardBreak()
	{
		m_ichrPos -= 1;
		m_ichrRunOffset -= 1;
		m_ichrLim = m_ichrPos;
	}

	void Restart();

	int NextGet(GrTableManager *, GrFeatureValues * pfval, int * ichrSegOffset, int * pcchr);

	void CurrentFeatures(GrTableManager * ptman, GrFeatureValues * pfval);

	//	For transduction logging:
	int GetLogData(GrTableManager * ptman, int * rgnChars, bool * rgfNewRun,
		GrFeatureValues * rgfval, int cchwBackup,
		int * pcchwMaxRaw);
	void GetLogDataRaw(GrTableManager * ptman, int cchw, int cchwBackup,
		int cchwMax16bit, int * prgnChars,
		utf16 * prgchw2, utf16 * prgchw3, utf16 * prgchw4, utf16 * prgchw5, utf16 * prgchw6, 
		int * prgichwRaw);

protected:
	void SetUpFeatureValues(GrTableManager * ptman, int ichr);
public:
	static utf32 Utf8ToUtf32(utf8 * prgchs8bit, int cchs, int * pcchsUsed);
	static utf32 Utf16ToUtf32(utf16 * prgchw16bit, int cchw, int * pcchwUsed);
	bool AtUnicodeCharBoundary(int cchr)
	{
		return AtUnicodeCharBoundary(m_pgts, cchr);
	}
	static bool AtUnicodeCharBoundary(ITextSource * pgts, int ichr);
	static bool AtUnicodeCharBoundary(utf8 * prgchs, int cchs, int ichs, UtfType utf);
	static bool AtUnicodeCharBoundary(utf16 * prgchw, int cchw, int ichr, UtfType utf);
	static bool FromSurrogatePair(utf16 chwIn1, utf16 chwIn2, unsigned int * pch32Out);
	static long DecodeUtf8(const utf8 * rgchUtf8, int cchUtf8, int * pcbOut);

protected:
	//	Instance variables:
	//	Hungarian note: chr = raw characters, chl = long characters (UTF-32)
	//		chs = short characters (UTF-8), chw = wide characters (UTF-16)
	ITextSource * m_pgts;	// string to render
	UtfType m_utf;	// what encoding form the text-source uses
	int m_ichrMin;	// official start of segment relative to beginning of string
	int m_ichrLim;	// end of stream (potential end of seg) relative to beginning of string
	int m_ichrPos;	// stream position (0 = start of string)
	bool m_fStartLine;	// true if a line-break character should be prepended
	bool m_fEndLine;	// true if a line-break character should be appended
	int m_cchrBackedUp;	// number of characters backed up before beginning of segment

	// We read a run's worth of data at a time and cache it in the following variables:
	int	m_cchlRunMax;	// size of buffer allocated
	int * m_prgchlRunText;	// buffer containing current run
	int m_ichrRunMin;		// start of run relative to beginning of string
	int m_ichrRunLim;		// end of run relative to beginning of string
	int m_ichlRunOffset;	// index into m_prgchlRunText; kPosInfinity if nothing set up
	int m_ichrRunOffset;	// corresponding index into text source
	GrFeatureValues m_fvalRunFeats;

	std::vector<int> m_vislotNextChunkMap; // maps from 16-bit chars to 32-bit chars & glyphs

	enum
	{
		kzUtf8Mask1 = 0x7F,
		kzUtf8Mask2 = 0x1F,
		kzUtf8Mask3 = 0x0F,
		kzUtf8Mask4 = 0x07,
		kzUtf8Mask5 = 0x03,
		kzUtf8Mask6 = 0x01
	};

	enum
	{
		kzUtf8Flag1 = 0x00,
		kzUtf8Flag2 = 0xC0,
		kzUtf8Flag3 = 0xE0,
		kzUtf8Flag4 = 0xF0,
		kzUtf8Flag5 = 0xF8,
		kzUtf8Flag6 = 0xFC
	};

	enum
	{
		kzByteMask = 0x3F,
		kzByteMark = 0x80,
		kzUtf8ByteShift = 6,
		kzUnicodeMax = 0x7FFFFFFF
	};

	enum
	{
		kzUtf16Shift	 = 10,
		kzUtf16Inc       = 0x2400,
		kzUtf16HighFirst = 0xD800,
		kzUtf16HighLast  = 0xDBFF,
		kzUtf16LowFirst  = 0xDC00,
		kzUtf16LowLast   = 0xDFFF
	};
};

} // namespace gr

#endif // !GR_CHARSTREAM_INCLUDED