aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--win32/PlatWin.cxx66
1 files changed, 33 insertions, 33 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 631c38ab5..f1d73c2d6 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -1593,40 +1593,44 @@ XYPOSITION SurfaceD2D::WidthText(Font &font_, const char *s, int len) {
void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) {
SetFont(font_);
- int fit = 0;
+ if (!pIDWriteFactory || !pTextFormat) {
+ // SetFont failed or no access to DirectWrite so give up.
+ return;
+ }
const TextWide tbuf(s, len, unicodeMode, codePageText);
TextPositions poses(tbuf.tlen);
- fit = tbuf.tlen;
+ // Initialize poses for safety.
+ std::fill(poses.buffer, poses.buffer + tbuf.tlen, 0.0f);
+ // Create a layout
+ IDWriteTextLayout *pTextLayout = 0;
+ const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout);
+ if (!SUCCEEDED(hrCreate)) {
+ return;
+ }
const int clusters = 1000;
DWRITE_CLUSTER_METRICS clusterMetrics[clusters];
UINT32 count = 0;
- if (pIDWriteFactory && pTextFormat) {
- SetFont(font_);
- // Create a layout
- IDWriteTextLayout *pTextLayout = 0;
- const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout);
- if (!SUCCEEDED(hr))
- return;
- if (!SUCCEEDED(pTextLayout->GetClusterMetrics(clusterMetrics, clusters, &count)))
- return;
- // A cluster may be more than one WCHAR, such as for "ffi" which is a ligature in the Candara font
- FLOAT position = 0.0f;
- size_t ti=0;
- for (size_t ci=0; ci<count; ci++) {
- for (size_t inCluster=0; inCluster<clusterMetrics[ci].length; inCluster++) {
- poses.buffer[ti++] = position + clusterMetrics[ci].width * (inCluster + 1) / clusterMetrics[ci].length;
- }
- position += clusterMetrics[ci].width;
+ const HRESULT hrGetCluster = pTextLayout->GetClusterMetrics(clusterMetrics, clusters, &count);
+ pTextLayout->Release();
+ if (!SUCCEEDED(hrGetCluster)) {
+ return;
+ }
+ // A cluster may be more than one WCHAR, such as for "ffi" which is a ligature in the Candara font
+ FLOAT position = 0.0f;
+ size_t ti=0;
+ for (size_t ci=0; ci<count; ci++) {
+ for (size_t inCluster=0; inCluster<clusterMetrics[ci].length; inCluster++) {
+ poses.buffer[ti++] = position + clusterMetrics[ci].width * (inCluster + 1) / clusterMetrics[ci].length;
}
- PLATFORM_ASSERT(ti == static_cast<size_t>(tbuf.tlen));
- pTextLayout->Release();
+ position += clusterMetrics[ci].width;
}
+ PLATFORM_ASSERT(ti == static_cast<size_t>(tbuf.tlen));
if (unicodeMode) {
// Map the widths given for UTF-16 characters back onto the UTF-8 input string
int ui=0;
const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
int i=0;
- while (ui<fit) {
+ while (ui<tbuf.tlen) {
const unsigned char uch = us[i];
unsigned int lenChar = 1;
if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) {
@@ -1650,26 +1654,22 @@ void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *
}
} else if (codePageText == 0) {
- // One character per position
+ // One char per position
PLATFORM_ASSERT(len == tbuf.tlen);
- for (size_t kk=0; kk<static_cast<size_t>(len); kk++) {
+ for (int kk=0; kk<tbuf.tlen; kk++) {
positions[kk] = poses.buffer[kk];
}
} else {
- // May be more than one byte per position
- unsigned int ui = 0;
- FLOAT position = 0.0f;
- for (int i=0; i<len;) {
- if (ui < count)
- position = poses.buffer[ui];
+ // May be one or two bytes per position
+ int ui = 0;
+ for (int i=0; i<len && ui<tbuf.tlen;) {
+ positions[i] = poses.buffer[ui];
if (Platform::IsDBCSLeadByte(codePageText, s[i])) {
- positions[i] = position;
- positions[i+1] = position;
+ positions[i+1] = poses.buffer[ui];
i += 2;
} else {
- positions[i] = position;
i++;
}