Exemple #1
0
BytevectorCell* StringCell::toUtf8Bytevector(World &world, SliceIndexType start, SliceIndexType end)
{
	CharRange range = charRange(start, end);

	if (range.isNull())
	{
		return nullptr;
	}

	ByteLengthType newLength = range.endPointer - range.startPointer;
	SharedByteArray *byteArray;

	if ((newLength == byteLength()) && !dataIsInline())
	{
		// Reuse our existing byte array
		byteArray = static_cast<HeapStringCell*>(this)->heapByteArray()->ref();
	}
	else
	{
		// Create a new byte array and initialize it
		byteArray = SharedByteArray::createInstance(newLength);
		memcpy(byteArray->data(), range.startPointer, newLength);
	}

	return BytevectorCell::withByteArray(world, byteArray, newLength);
}
Exemple #2
0
StringCell* StringCell::copy(World &world, SliceIndexType start, SliceIndexType end)
{
	// Allocating a string below can actually change "this"
	// That is super annoying
	StringCell *oldThis = const_cast<StringCell*>(this);
	alloc::StringRef thisRef(world, oldThis);

	CharRange range = charRange(start, end);

	if (range.isNull())
	{
		// Invalid range
		return nullptr;
	}

	if ((range.charCount == charLength()) && !dataIsInline())
	{
		// We're copying the whole string
		// Share our byte array
		void *cellPlacement = alloc::allocateCells(world);
		HeapStringCell *heapThis = static_cast<HeapStringCell*>(thisRef.data());

		return new (cellPlacement) HeapStringCell(
				heapThis->heapByteArray()->ref(),
				heapThis->byteLength(),
				heapThis->charLength()
		);
	}

	const ByteLengthType newByteLength = range.byteCount();

	// Create the new string
	auto newString = StringCell::createUninitialized(world, newByteLength, range.charCount);
	
	if (thisRef->dataIsInline() && (oldThis != thisRef.data()))
	{
		// The allocator ran and moved us along with our inline data
		// We have to update our range
		ptrdiff_t byteDelta = reinterpret_cast<std::uint8_t*>(thisRef.data()) -
			                   reinterpret_cast<std::uint8_t*>(oldThis);

		range.relocate(byteDelta);
	}

	std::uint8_t *newUtf8Data = newString->utf8Data();

	memcpy(newUtf8Data, range.startPointer, newByteLength);

	return newString;
}
Exemple #3
0
bool StringCell::fill(UnicodeChar unicodeChar, SliceIndexType start, SliceIndexType end)
{
	assert(unicodeChar.isValid());
	CharRange range = charRange(start, end);

	if (range.isNull())
	{
		// Invalid range
		return false;
	}

	// Encode the new character
	utf8::EncodedChar encoded(utf8::encodeChar(unicodeChar));
	return replaceBytes(range, encoded.data, encoded.size, range.charCount);
}
// --------------------------------------------------------------
void
GFontWin32GDIPlus::GetExtent( const char * str, int inCharCount, float * outWidth, 
					   float * outHeight, VGDevice * context ) const 
{
	if (!inCharCount) {
		*outWidth = *outHeight = 0;
		return;
	}
	// convert input string
	DWORD count = (DWORD)mbstowcs(NULL, str, inCharCount);
	WCHAR * wstr = (WCHAR*) malloc ((count + 1) * sizeof(WCHAR));
	mbstowcs(wstr, str, inCharCount);

	//std::string s(str);
	//std::wstring wstr(s.length(),L' ');
	//std::copy(s.begin(), s.end(), wstr.begin());

	Graphics* gdiContext = (Graphics*) GetContext( context );

/*	-- known Gdi+ issue: 
	We must use the following way to determine correct font extent 
	because typical Graphics::MeasureString() method doesn't work
	properly (return values are incorrect due to antialiasing)
*/
	Font* dgiFont = GetNativeFont();

	// Layout rectangles used for drawing strings
	RectF   layoutRect_A(0.0f, 0.0f, 1300.0f, 1300.0f);
	// 1 range of character positions within the string
	CharacterRange charRange(0, inCharCount);
	// String format used to apply to string when drawing
	StringFormat strFormat;
	// Set three ranges of character positions.
	strFormat.SetMeasurableCharacterRanges(1, &charRange);
	Region *pCharRangeRegions = new Region();

	// Get the regions that correspond to the ranges within the string when
	// layout rectangle A is used. 
	gdiContext->MeasureCharacterRanges( wstr, inCharCount, dgiFont, layoutRect_A, &strFormat, 1, pCharRangeRegions);

	RectF boundRect;
	pCharRangeRegions->GetBounds( &boundRect, gdiContext);

	*outWidth = boundRect.Width;
	*outHeight = boundRect.Height;
	free (wstr);
}
Exemple #5
0
double ASSISTANT::Text::GetTextWidth(const _TCHAR *textString, int textLength, LOGFONT *logFont)
{
   if (textLength == 0)
      return 0;

   HDC hdc = ::CreateCompatibleDC(NULL);

   //Gdiplus::Graphics graphics(hdc);

   WCHAR *wcString = (WCHAR *)malloc((textLength+1)*sizeof(WCHAR));

#ifdef _UNICODE
   wcscpy(wcString, textString);
#else
   MultiByteToWideChar(CP_ACP, 0, textString, textLength+1, 
                                  wcString, textLength+1);
#endif

   
   Gdiplus::RectF bbox;
   Gdiplus::Font font(hdc, logFont);
   
   Gdiplus::Graphics graphics(hdc);
   graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
   Gdiplus::StringFormat strFormat(Gdiplus::StringFormatFlagsMeasureTrailingSpaces);

   graphics.MeasureString(wcString, textLength, &font, Gdiplus::PointF(0.0, 0.0), &strFormat, &bbox);

   Gdiplus::CharacterRange charRange(0, textLength);
   strFormat.SetMeasurableCharacterRanges(1, &charRange);
   Gdiplus::Region pRangeRegion[1];
   graphics.MeasureCharacterRanges(wcString, textLength,
                                   &font, bbox, &strFormat, 1, pRangeRegion);
   // get bounding rectangle
   Gdiplus::RectF rect;
   pRangeRegion[0].GetBounds(&rect, &graphics);

   if (wcString)
      delete wcString;

   ::DeleteObject(hdc);
   ::DeleteDC(hdc);

   return rect.Width;
}
Exemple #6
0
bool StringCell::replace(CharLengthType offset, const StringCell *from, SliceIndexType fromStart, SliceIndexType fromEnd)
{
	CharRange fromRange = const_cast<StringCell*>(from)->charRange(fromStart, fromEnd);

	if (fromRange.isNull())
	{
		return false;
	}

	CharRange toRange = charRange(offset, offset + fromRange.charCount);

	if (toRange.isNull() || (toRange.charCount != fromRange.charCount))
	{
		return false;
	}

	return replaceBytes(toRange, fromRange.startPointer, fromRange.byteCount(), 1);
}
// --------------------------------------------------------------
void	
GFontWin32GDIPlus::GetExtent( unsigned char c, float * outWidth, 
					          float * outHeight, VGDevice * context ) const
{
	WCHAR wstr [] = L"0";
	mbstowcs(wstr, (const char*)&c, 1);

	Graphics* gdiContext = (Graphics*) GetContext( context );

/*	-- known Gdi+ issue: 
	We must use the following way to determine correct font extent 
	because typical Graphics::MeasureString() method doesn't work
	properly (return values are incorrect due to antialiasing)
*/
	Font* dgiFont = GetNativeFont();

	// Layout rectangles used for drawing strings
	RectF   layoutRect_A(0.0f, 0.0f, 1300.0f, 1300.0f);
	// 1 range of character positions within the string
	CharacterRange charRange(0, 1);
	// String format used to apply to string when drawing
	StringFormat strFormat;
	// Set three ranges of character positions.
	strFormat.SetMeasurableCharacterRanges(1, &charRange);
	Region *pCharRangeRegions = new Region();

	// Get the regions that correspond to the ranges within the string when
	// layout rectangle A is used. 
	gdiContext->MeasureCharacterRanges( wstr, 1, dgiFont, layoutRect_A, &strFormat, 1, pCharRangeRegions);

	RectF boundRect;
	pCharRangeRegions->GetBounds( &boundRect, gdiContext);

	*outHeight = boundRect.Height;
	*outWidth = boundRect.Width;
	// in some cases (when some symbols must be forced into char map), extent needs to be fixed  
	if (c == 139) *outWidth = 6.0;

}
Exemple #8
0
void ASSISTANT::Text::Draw(CDC *pDC, float _zoomFactor, double dOffX, double dOffY)
{
   if (!visible) return;
   
   if (text.IsEmpty())
      return;

   Gdiplus::Graphics graphics(pDC->m_hDC);
   graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);

   // Move and Scale
   graphics.TranslateTransform((Gdiplus::REAL)dOffX, (Gdiplus::REAL)dOffY);
   
   Gdiplus::Font gdipFont(pDC->m_hDC, &m_logFont);
   Gdiplus::FontFamily fontFamily;
   gdipFont.GetFamily(&fontFamily);

   int fontStyle = GetValidFontStyle(fontFamily);
   Gdiplus::REAL ascent = fontFamily.GetCellAscent(fontStyle) * 
                          (gdipFont.GetSize() / fontFamily.GetEmHeight(fontStyle));

   Gdiplus::PointF drawPoint;
   drawPoint.X = (Gdiplus::REAL)m_dX;
   drawPoint.Y = (Gdiplus::REAL)(m_dY - ascent);

   // convert text string to WCHAR format
   int iStringLength = text.GetLength();
   WCHAR *wcString = (WCHAR *)malloc((iStringLength+1)*sizeof(WCHAR)); // +1 for null termination
#ifdef _UNICODE
   wcscpy(wcString, text);
#else
   MultiByteToWideChar(CP_ACP, 0, text, iStringLength+1, 
                       wcString, iStringLength+1);
#endif

   // compute real text width
   Gdiplus::StringFormat measureStringFormat(Gdiplus::StringFormatFlagsMeasureTrailingSpaces);
   Gdiplus::RectF bbox;
   
   graphics.MeasureString(wcString, iStringLength, &gdipFont, Gdiplus::PointF(0.0, 0.0), &measureStringFormat, &bbox);

   Gdiplus::CharacterRange charRange(0, iStringLength);
   measureStringFormat.SetMeasurableCharacterRanges(1, &charRange);
   Gdiplus::Region pRangeRegion[1];
   graphics.MeasureCharacterRanges(wcString, iStringLength,
                                   &gdipFont, bbox, &measureStringFormat, 1, pRangeRegion);
   // get bounding rectangle
   Gdiplus::RectF rect;
   pRangeRegion[0].GetBounds(&rect, &graphics);

   Gdiplus::REAL realTextWidth = rect.Width;
   if (iStringLength > 1 && m_dWidth != 0 && realTextWidth != m_dWidth)
   {
      Gdiplus::REAL scaleX = (Gdiplus::REAL)(m_dWidth / realTextWidth);
      graphics.ScaleTransform(scaleX, 1.0);
      drawPoint.X = (Gdiplus::REAL)(m_dX / scaleX); //(x_*scaleX - x_);
   }
   // the text should begin at x, y
   drawPoint.X -= rect.X;

   graphics.ScaleTransform(_zoomFactor, _zoomFactor);

   Gdiplus::Color clrText(m_argbLineColor);
   Gdiplus::SolidBrush solidBrush(clrText);
   graphics.DrawString(wcString, iStringLength, &gdipFont, drawPoint, &measureStringFormat, &solidBrush);
   
   if (wcString)
      delete wcString;
}