Exemplo n.º 1
0
void DrawString(Vector2 pos, int flags, Colour colour, const char* txt, ...)
{
	char buf[512];

	va_list ap;

	va_start(ap, txt);
	_vsnprintf_s(buf, sizeof(buf), _TRUNCATE, txt, ap);
	va_end(ap);

	if (flags == kTextCentre)
		pos.x -= MeasureString(txt) * 0.5f;
	else if (flags == kTextRight)
		pos.x -= MeasureString(txt);

	const char* letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.:/-!@";

	for(const char* p = buf; *p != '\0'; p++)
	{
		int c = toupper(*p);
		int sprite = -1;

		if (const char* ofs = strchr(letters, c))
			sprite = 256 + (int)(intptr_t)(ofs - letters);

		if (sprite >= 0)
			DrawChar(pos, Vector2(1.0f), sprite, 0, colour); 

		pos.x += MeasureChar(c);
	}
}
void ErrorPopUpScreen::Draw(float totalTime, float elapsedTime)
{
    UNREFERENCED_PARAMETER(totalTime);
    UNREFERENCED_PARAMETER(elapsedTime);

    auto screenManager = Manager();
    auto spriteBatch = screenManager->GetSpriteBatch();
    auto spriteFont = screenManager->GetSpriteFont();
    auto blendStates = screenManager->GetCommonStates();
    auto viewportBounds = screenManager->GetScreenBounds();
    float viewportWidth = float(viewportBounds.right);
    float viewportHeight = float(viewportBounds.bottom);
    auto scaleMatrix = DX::GetScaleMatrixForWindow(screenManager->GetWindowBounds());

    // calculate position and size of error message
    XMFLOAT2 errorMsgPosition = XMFLOAT2(0, viewportHeight / 2.0f);
    XMVECTORF32 errorMsgColor = Colors::Yellow;
    XMFLOAT2 origin = XMFLOAT2(0, spriteFont->GetLineSpacing() / 2.0f);
    XMVECTOR size = spriteFont->MeasureString(m_errorMessage.c_str());
    errorMsgPosition.x = viewportWidth / 2.0f - XMVectorGetX(size) / 2.0f;

    // create a rectangle representing the screen dimensions of the error message background rectangle
    long rectangleWidth = long(std::min(std::max(XMVectorGetX(size) + 100.0f, 600.0f), viewportWidth));
    long rectangleHeight = long(spriteFont->GetLineSpacing() * 6.0f);
    long rectangleLeft = long(viewportWidth / 2.0f) - (rectangleWidth / 2);
    long rectangleTop = long(errorMsgPosition.y + spriteFont->GetLineSpacing()) - (rectangleHeight / 2);
    RECT backgroundRectangle = { rectangleLeft, rectangleTop, rectangleLeft + rectangleWidth, rectangleTop + rectangleHeight };

    spriteBatch->Begin(SpriteSortMode_Deferred, blendStates->NonPremultiplied(), nullptr, nullptr, nullptr, nullptr, scaleMatrix);

    // draw a background color for the rectangle
    spriteBatch->Draw(m_backgroundTexture->GetResourceViewTemporary(), backgroundRectangle, BackgroundColor);

    // draw error message in the middle of the screen
    spriteFont->DrawString(spriteBatch.get(), m_errorMessage.c_str(), errorMsgPosition, errorMsgColor, 0, origin);

    // draw continuation prompt
    winrt::hstring continuePrompt = L"Press (A) to Continue";
    if (!InputState::IsAnyGamepadConnected())
    {
        continuePrompt = L"Press Enter to Continue";
    }
    errorMsgPosition.y += spriteFont->GetLineSpacing();
    size = spriteFont->MeasureString(continuePrompt.c_str());
    errorMsgPosition.x = viewportWidth / 2.0f - XMVectorGetX(size) / 2.0f;
    spriteFont->DrawString(spriteBatch.get(), continuePrompt.c_str(), errorMsgPosition, Colors::Yellow, 0, origin);

    spriteBatch->End();
}
Exemplo n.º 3
0
void DrawStringB(int x, int y, int r, int g, int b, char *str)
{
	int len = 0;
	uint32_t color = 0;
				
	len = MeasureString(str);
	len *= 5;
	
	color = graphics_make_color(r, g, b, 0xff);
	
    graphics_draw_box(__dc, x, y-1, len + 3, fh, graphics_make_color(0, 0, 0, 0));
	graphics_set_color(color, 0x00000000);
	graphics_draw_text(__dc, x, y, str);
}
Exemplo n.º 4
0
GpStatus
cairo_DrawString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc, 
	GDIPCONST GpStringFormat *format, GpBrush *brush)
{
	cairo_matrix_t SavedMatrix;
	GpStringFormat *fmt;
	GpStringDetailStruct *StringDetails;
	WCHAR *CleanString;
	GpDrawTextData data; /* avoid recomputation of stuff done while measuring */
	int StringLen = length;

	GpStatus status = AllocStringData (&CleanString, &StringDetails, length);
	if (status != Ok)
		return status;

	/* a NULL format is valid, it means get the generic default values (and free them later) */
	if (!format) {
		GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt);
	} else {
		fmt = (GpStringFormat *)format;
	}

	/* is the following ok ? */
	cairo_get_font_matrix (graphics->ct, &SavedMatrix);

	status = MeasureString (graphics, stringUnicode, &StringLen, font, rc, fmt, brush, NULL, NULL, NULL, CleanString, StringDetails, &data);
	if ((status == Ok) && (StringLen > 0)) {
		status = DrawString (graphics, stringUnicode, StringLen, font, rc, fmt, brush, CleanString, StringDetails, &data);
	}

	/* Restore matrix to original values */
	cairo_set_font_matrix (graphics->ct, &SavedMatrix);

	/* Cleanup */
	GdipFree (CleanString);
	GdipFree (StringDetails);

	/* we must delete the default stringformat (when one wasn't provided by the caller) */
	if (format != fmt)
		GdipDeleteStringFormat (fmt);

	return status;
}
Exemplo n.º 5
0
GpStatus
cairo_MeasureString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc,
	GDIPCONST GpStringFormat *format,  RectF *boundingBox, int *codepointsFitted, int *linesFilled)
{
	cairo_matrix_t SavedMatrix;
	GpStringFormat *fmt;
	GpStringDetailStruct *StringDetails;
	WCHAR *CleanString;
	int StringLen = length;
	GpStatus status;

	status = AllocStringData (&CleanString, &StringDetails, length);
	if (status != Ok)
		return status;

	/* a NULL format is valid, it means get the generic default values (and free them later) */
	if (!format) {
		GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt);
	} else {
		fmt = (GpStringFormat *)format;
	}

	/* is the following ok ? */
	cairo_get_font_matrix (graphics->ct, &SavedMatrix);

	status = MeasureString (graphics, stringUnicode, &StringLen, font, rc, fmt, NULL, boundingBox, codepointsFitted, 
		linesFilled, CleanString, StringDetails, NULL);

	/* Restore matrix to original values */
	cairo_set_font_matrix (graphics->ct, &SavedMatrix);

	/* Cleanup */
	GdipFree (CleanString);
	GdipFree (StringDetails);

	/* we must delete the default stringformat (when one wasn't provided by the caller) */
	if (format != fmt)
		GdipDeleteStringFormat (fmt);

	return status;
}
void FGameplayDebuggerCanvasContext::Print(const FColor& Color, const FString& String)
{
	FTaggedStringParser Parser(Color);
	Parser.ParseString(String);

	const float LineHeight = GetLineHeight();
	for (int32 NodeIdx = 0; NodeIdx < Parser.NodeList.Num(); NodeIdx++)
	{
		const FTaggedStringParser::FNode& NodeData = Parser.NodeList[NodeIdx];
		if (NodeData.bNewLine)
		{
			if (Canvas.IsValid() && (CursorY + LineHeight) > Canvas->ClipY)
			{
				DefaultX += Canvas->ClipX / 2;
				CursorY = 0.0f;
			}

			CursorX = DefaultX;
			CursorY += LineHeight;
		}

		if (NodeData.String.Len() > 0)
		{
			float SizeX = 0.0f, SizeY = 0.0f;
			MeasureString(NodeData.String, SizeX, SizeY);

			FCanvasTextItem TextItem(FVector2D::ZeroVector, FText::FromString(NodeData.String), Font.Get(), FLinearColor(NodeData.Color));
			if (FontRenderInfo.bEnableShadow)
			{
				TextItem.EnableShadow(FColor::Black, FVector2D(1, 1));
			}

			DrawItem(TextItem, CursorX, CursorY);
			CursorX += SizeX;
		}
	}

	MoveToNewLine();
}
Exemplo n.º 7
0
void CCherryStatic::ResizeWindow()
{
	CRect textRect;
	CString strText;
	
	GetWindowText(strText);

	if (!strText.IsEmpty())
	{
		CPaintDC dc(this);
		Graphics graphics(dc.GetSafeHdc());

		textRect = MeasureString(&graphics, strText);
	}

	CRect windowRect;
	GetWindowRect(&windowRect);
	GetParent()->ScreenToClient(&windowRect);

	windowRect.right = windowRect.left + textRect.Width() + 3;	// 오차를 보정하기 위한 3
	windowRect.bottom = windowRect.top + textRect.Height();

	MoveWindow(windowRect);
}
Exemplo n.º 8
0
GpStatus
cairo_MeasureCharacterRanges (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, 
	GDIPCONST GpRectF *layout, GDIPCONST GpStringFormat *format, int regionCount, GpRegion **regions)
{
	int			i, j, start, end;
	int			lineHeight;
	CharacterRange		range;
	GpStringDetailStruct*	StringDetails;
	RectF			charRect;
	RectF 			rc_coords, *layoutRect = &rc_coords;
	BOOL			optimize_convert;
	WCHAR *CleanString;
	GpDrawTextData data; /* avoid recomputation of stuff done while measuring */
	int StringLen = length;

	GpStatus status = AllocStringData (&CleanString, &StringDetails, length);
	if (status != Ok)
		return status;

	/* avoid conversion if possible */
	optimize_convert = OPTIMIZE_CONVERSION (graphics);
	if (optimize_convert) {
		layoutRect->X = layout->X;
		layoutRect->Y = layout->Y;
		layoutRect->Width = layout->Width;
		layoutRect->Height = layout->Height;
	} else {
		layoutRect->X = gdip_unitx_convgr (graphics, layout->X);
		layoutRect->Y = gdip_unity_convgr (graphics, layout->Y);
		layoutRect->Width = gdip_unitx_convgr (graphics, layout->Width);
		layoutRect->Height = gdip_unity_convgr (graphics, layout->Height);
	}

	if (layoutRect->Width <= 0.0) {
		if (layoutRect->Height < 0.0) {
			/* special case only if BOTH values are negative */
			for (i = 0; i < format->charRangeCount; i++)
				GdipSetInfinite (regions [i]);
			return Ok;
		} else {
			layoutRect->Width = REGION_INFINITE_LENGTH;
		}
	}
	if (layoutRect->Height <= 0.0) {
		layoutRect->Height = REGION_INFINITE_LENGTH;
	}

	/* string measurements */
	status = MeasureString (graphics, stringUnicode, &StringLen, font, layoutRect, format, NULL, NULL, NULL, NULL,
		CleanString, StringDetails, &data);
	if (status != Ok)
		goto cleanup;

	lineHeight = data.line_height + data.descent;

	/* Create a region for every char range */
	for (i = 0; i < format->charRangeCount; i++) {
		range = format->charRanges [i];
		GdipSetEmpty (regions [i]); 

		if (range.Length > 0)
			start = range.First;
		else
			start = range.First + range.Length;

		end = start + range.Length;

		/* sanity check on charRange. negative lengths are allowed */
		if (range.First < 0) {
			status = InvalidParameter;
			goto cleanup;
		}

		if ((start < 0) || (end > length)) {
			status = InvalidParameter;
			goto cleanup;
		}

		/* calculate the regions */
		for (j = start; j < end; j++) {

			/* the prefix char (&) always count - even if we are not actually print it as a char */
			if ((StringDetails[j].Flags & STRING_DETAIL_HOTKEY) && (format->hotkeyPrefix != HotkeyPrefixNone)) {
				end--; /* '&' count as invisible char */
				continue;
			}

			/* workaround the fact that current implementation thinks LF is on the next line */
			if ((j == end - 1) && (StringDetails[j].Flags & STRING_DETAIL_LF))
				continue;

			if (format->formatFlags & StringFormatFlagsDirectionVertical) {
				charRect.X = layoutRect->X + StringDetails [j].PosY;
				charRect.Y = layoutRect->Y + StringDetails [j].PosX;
				charRect.Width = lineHeight;
				charRect.Height = StringDetails [j].Width;
			} else {
				charRect.X = layoutRect->X + StringDetails [j].PosX;
				charRect.Y = layoutRect->Y + StringDetails [j].PosY;
				charRect.Width = StringDetails [j].Width;
				charRect.Height = lineHeight;
			}

			if (optimize_convert) {
				charRect.X = gdip_convgr_unitx (graphics, charRect.X);
				charRect.Y = gdip_convgr_unity (graphics, charRect.Y);
				charRect.Width = gdip_convgr_unitx (graphics, charRect.Width);
				charRect.Height = gdip_convgr_unity (graphics, charRect.Height);
			}

			status = GdipCombineRegionRect (regions [i], &charRect, CombineModeUnion);
			if (status != Ok)
				break;
		}
		if (status != Ok)
			break;
	}

cleanup:
	/* Cleanup */
	GdipFree (CleanString);
	GdipFree (StringDetails);

	return status;
}
Exemplo n.º 9
0
void cgRender::RenderString( LPCTSTR lpctText, int nTextLen, 
	const cgRectF& rect, cgID font, float space ,
	cgColor color, unsigned style, float scale )
{
	
#ifdef _USE_HARDWARE_FONT_

	cgFont * pkFont = cgFontManager::Get()->FindFont(font);
	if (!pkFont)
		return ;

	// 计算字符串占得宽高
	float textWidth = rect.w;
	float textHeight = rect.h;
	MeasureString(lpctText, nTextLen, font, textWidth, textHeight, space, scale);
	
	// 计算字符串绘制的起始位置
	float beginX = rect.x;
	float beginY = rect.y;

	if (style&DT_RIGHT)
		beginX = rect.x+rect.w-textWidth;
	
	if (style&DT_CENTER)
		beginX = (rect.w-textWidth)/2+rect.x;
	
	if (style&DT_BOTTOM)
		beginY = rect.y+rect.h-textHeight;
	
	if (style&DT_VCENTER)
		beginY = (rect.h-textHeight)/2+rect.y;
	
	float nFontHeight = pkFont->GetConfig()->uHeight*scale;

	float drawX = beginX;
	float drawY = beginY;

	for (int i = 0; i < nTextLen; ++i)
	{
		TCHAR ch = lpctText[i];
		
		if (ch == TEXT('\n') )
		{
			drawY += (space+nFontHeight);
			drawX = beginX;
		}else
		{
			float charWidth = pkFont->GetCharWidthInPixel(ch)*scale;
			if(drawX + charWidth > beginX+textWidth+0.5f)
			{
				drawY += (space+nFontHeight);
				drawX = beginX;
			}

			pkFont->DrawChar(ch, drawX, drawY, color, scale);
			drawX += charWidth;
		}
	
		
	}

#else
	m_pkRenderImpl->RenderTextDirectly(lpctText, nTextLen, rect, font, color, style);
	m_pkRenderImpl->SetRenderDirty();
#endif
}
Exemplo n.º 10
0
void DrawScreen(screen_enum_t scn)
{
	int i,j;
	int sWidth = 0;

	if(bDisplayInitialized == 0) return;

	xSemaphoreTake(xDispSemaphore, portMAX_DELAY);
	{

		SetDrawingLayer();
		switch(scn)
		{
		case EmpLoggedInScn:
			Background_color(color_black);
			Text_color(color_white);
			Clear_Active_Window();
			Show_String18(gArial18, "Client Name:", 55,5);
			Show_String18(gArial24, "Vigelette, George", 55,28); // time while the font is still loaded
			Show_String18(gArial24, "11:32 AM", 385,28); // time while the font is still loaded

			DisplayImageBlockMode(g3gIcon20.start_addr ,400, 3, g3gIcon20.image_width, g3gIcon20.image_height);
	//
	//			Layer1_Visible();
	//			Write_To_Bank1();
	//			Active_Window(0,479,0,271);

			// battery
			DisplayImageBlockMode(gBatteryIcons.start_addr,427, 3, gBatteryIcons.image_width, 20);

			// buttons
			// Row 1
			DisplayImageBlockMode(gBtnEndShift.start_addr,20, 63, gBtnEndShift.image_width, gBtnEndShift.image_height);
			DisplayImageBlockMode(gBtnTimesheet.start_addr,250, 63, gBtnTimesheet.image_width, gBtnTimesheet.image_height);

			// Row 2
			DisplayImageBlockMode(gBtnTaskList.start_addr,20, 123, gBtnTaskList.image_width, gBtnTaskList.image_height);
			DisplayImageBlockMode(gBtnSchedule.start_addr,250, 123, gBtnSchedule.image_width, gBtnSchedule.image_height);

			// Row 3
			DisplayImageBlockMode(gBtnMessages.start_addr,20, 183, gBtnMessages.image_width, gBtnMessages.image_height);
			DisplayImageBlockMode(gBtnExit.start_addr,250, 183, gBtnExit.image_width, gBtnExit.image_height);

			sWidth = MeasureString(gArial24, "Jan 21, 2013");
			Show_String18(gArial24, "Jan 21, 2013", (480 - sWidth)/2 ,250);

			break;
		case EmpLoggedOutScn:
			break;
		case ClientScn:
			break;
		case ActivationScn:
			break;
		case TestScn:
			// bte fill
			Background_color(color_black);
			Text_color(color_white);
			Graphic_Mode();
			BTE_Size_setting(15,68);
			BTE_ROP_Code(0xcc);	 //set BTE solid fill
			for(i=0;i<32;i++)
			{
				Text_Foreground_Color(i,0,0);
				BTE_Source_Destination(0,i*15,0,0);
				BTE_enable();
				Chk_Busy_BTE();

				Text_Foreground_Color(0,i*2,0);
				BTE_Source_Destination(0,i*15,0,68);
				BTE_enable();
				Chk_Busy_BTE();

				Text_Foreground_Color(0,0,i);
				BTE_Source_Destination(0,i*15,0,136);
				BTE_enable();
				Chk_Busy_BTE();

				Text_Foreground_Color(i,i*2,i);
				BTE_Source_Destination(0,i*15,0,204);
				BTE_enable();
				Chk_Busy_BTE();
			}
			break;
		case ConfigurationScn:
			Internal_CGROM();
			Font_size_16x16_8x16();
			Background_color(color_blue);
			Text_color(color_white);
			Clear_Active_Window();
			Font_Coordinate(5,5);
			Show_String("Safe-Link Device Configuration ",0);
			break;
		case AuthenticatingScn:
			break;
		case MessageListScn:
			break;
		case NewMessageScn:
			break;
		case ReadMessageScn:
			break;
		case TaskListScn:
			break;
		case TaskViewScn:
			break;
		case ScheduleScn:
			break;
		case TimeApproveScn:
			break;
		case LockedScn:
			Active_Window(0,479,0,271);
			DisplayImageBlockMode(gDeviceLockedScreen.start_addr, 0,0,gDeviceLockedScreen.image_width, gDeviceLockedScreen.image_height);
			break;
		case SplashScn:
			Active_Window(0,479,0,271);
			DisplayImageBlockMode(gsplashScreen.start_addr, 0,0,gsplashScreen.image_width, gsplashScreen.image_height);
			Text_color(color_white);
			Geometric_Coordinate(212,268,108,164);
			Draw_square();
			Text_color(color_black);
			Geometric_Coordinate(213,267,109,163);
			Draw_square_fill();
			Active_Window(0,479,0,271);
			DisplayImageBlockMode(gCycle.start_addr, 216,112,gCycle.image_width, gCycle.image_height);

			break;
		case LoadingAnim:
			Active_Window(0,479,0,271);
			Background_color(color_black);
			Text_color(color_white);
			Graphic_Mode();
			Clear_Active_Window();
			Show_String18(gArialBlack24, "Loading", 206 ,116);
			DisplayImageBlockMode(gProgressBar.start_addr,153, 145, gProgressBar.image_width, 14);
			break;
		default:
			DisplayImageBlockMode(gsplashScreen.start_addr, 0,0,gsplashScreen.image_width, gsplashScreen.image_height);
			break;
		}

		ShowNextScene();
		xSemaphoreGive(xDispSemaphore);
	}
}
Exemplo n.º 11
0
void duXmlStatic::ParseTextParam()
{
	LPCTSTR lpszText = GetText();
	if (lpszText == NULL || *lpszText == 0)
		return;
	
	TiXmlDocument *pXmlDoc = new TiXmlDocument;
	pXmlDoc->Parse(lpszText, NULL);
	
	TiXmlElement *pTextElement = pXmlDoc->FirstChildElement(_T("text"));
	if (pTextElement == NULL)
	{
		delete pXmlDoc;
		return;
	}
	
	Destroy();
	
	m_nParagraphSpace = ReadXmlAttributeInt(pTextElement, _T("ParagraphSpace"));
	ReadXmlAttributeText(pTextElement, _T("Font"), m_szDefaultFont, MAX_NAME);
	m_clrDefault = ReadXmlAttributeColor(pTextElement, _T("Color"));

	TiXmlNode *pChildNode = pTextElement->FirstChild();
	while (pChildNode)
	{
		if (pChildNode->Type() == TiXmlNode::ELEMENT)
		{
			TiXmlElement *pThis = pChildNode->ToElement();
			if (lstrcmpi(pThis->Value(), _T("br")) == 0)
			{
				XMLTEXTHEAD *pBrText = ParseBrText(pThis);
				if (pBrText)
					m_vtXmlText.push_back(pBrText);
			}
			else if (lstrcmpi(pThis->Value(), _T("text")) == 0)
			{
				XMLTEXTHEAD *pFormatText = ParseFormatText(pThis);
				if (pFormatText)
					m_vtXmlText.push_back(pFormatText);
			}
		}
		else if (pChildNode->Type() == TiXmlNode::TEXT)
		{
			TiXmlText *pThis = pChildNode->ToText();
			XMLTEXTHEAD *pNormalText = ParseNormalText(pThis);
			if (pNormalText)
				m_vtXmlText.push_back(pNormalText);
		}
		
		pChildNode = pChildNode->NextSibling();
	}
	
	//////////////////////////////////////////////////////////////////
	duRect rectStatic;
	Plugin_GetRect(this, &rectStatic);
	rectStatic.OffsetRect(-rectStatic.left, -rectStatic.top);
	
	int nTextCount = (int)m_vtXmlText.size();
	int i;
	int nCurrentLineWidth = 0;
	int nMaxHeight = 0;
	
	XMLSTATICLINE *pThisLine = NULL;
	for (i = 0;i < nTextCount; i++)
	{
		XMLTEXTHEAD *pTextHead = m_vtXmlText[i];
		MeasureString(pTextHead);
		
		if (pTextHead->size.cy > nMaxHeight)
			nMaxHeight = pTextHead->size.cy;

		if (pTextHead->enType == BRTEXT)
		{
			XMLSTATICLINESEGMENT *pLineSegment = new XMLSTATICLINESEGMENT;
			pLineSegment->pTextHead = pTextHead;
			pLineSegment->lpString = g_emptyString;
			pLineSegment->nStringWidth = 0;
			pLineSegment->nStringPosInTextHead = 0;
			pLineSegment->nWidth = pTextHead->size.cx;
			pLineSegment->nHeight = pTextHead->size.cy;

			if (pThisLine == NULL)
			{
				pThisLine = new XMLSTATICLINE;
				pThisLine->nWidth = 0;
				pThisLine->nHeight = 0;
				pThisLine->vtLineSegment.clear();
				m_vtLine.push_back(pThisLine);
			}

			pThisLine->nWidth = nCurrentLineWidth;
			pThisLine->nHeight = nMaxHeight;
			pThisLine->vtLineSegment.push_back(pLineSegment);

			pThisLine = NULL;
			nCurrentLineWidth = 0;
		}
		else
		{
			nCurrentLineWidth += pTextHead->size.cx;
			if (nCurrentLineWidth > rectStatic.Width())
			{
				XMLSTATICLINESEGMENT *pLineSegment = MeasureStringBreakPos(pTextHead, 0, nCurrentLineWidth - pTextHead->size.cx, rectStatic.Width());
				if (pLineSegment == NULL)
					_TRACE(_T("Error: pLineSegment is NULL\n"));
				
				if (pThisLine == NULL)
				{
					pThisLine = new XMLSTATICLINE;
					pThisLine->nWidth = 0;
					pThisLine->nHeight = 0;
					pThisLine->vtLineSegment.clear();
					m_vtLine.push_back(pThisLine);
				}

				pThisLine->nWidth = nCurrentLineWidth - pTextHead->size.cx + pLineSegment->nWidth;
				pThisLine->nHeight = nMaxHeight;
				pThisLine->vtLineSegment.push_back(pLineSegment);
				
				nMaxHeight = 0;
				
				int nRemainWidth = nCurrentLineWidth - pThisLine->nWidth;
				XMLSTATICLINESEGMENT *pLineSegment2 = pLineSegment;
				while (nRemainWidth > rectStatic.Width())
				{
					pLineSegment2 = MeasureStringBreakPos(pTextHead, pLineSegment2->nStringPosInTextHead + pLineSegment2->nStringWidth, 0, rectStatic.Width());
					if (pLineSegment2 == NULL)
						_TRACE(_T("Error: pLineSegment2 is NULL\n"));

					pThisLine = new XMLSTATICLINE;
					pThisLine->nWidth = pLineSegment2->nWidth;
					pThisLine->nHeight = pLineSegment2->nHeight;
					pThisLine->vtLineSegment.push_back(pLineSegment2);
					m_vtLine.push_back(pThisLine);

					nRemainWidth -= pLineSegment2->nWidth;
				}
				
				if (pLineSegment2->nStringPosInTextHead + pLineSegment2->nStringWidth < pLineSegment2->pTextHead->strText.length())
				{
					pThisLine = new XMLSTATICLINE;
					XMLSTATICLINESEGMENT *pLineSegment3 = new XMLSTATICLINESEGMENT;
					pLineSegment3->pTextHead = pTextHead;
					pLineSegment3->lpString = pLineSegment2->lpString + pLineSegment2->nStringWidth;
					pLineSegment3->nStringPosInTextHead = pLineSegment2->nStringPosInTextHead + pLineSegment2->nStringWidth ;
					pLineSegment3->nStringWidth = pLineSegment2->pTextHead->strText.length() - pLineSegment3->nStringPosInTextHead;
					pLineSegment3->nWidth = nRemainWidth;
					pLineSegment3->nHeight = pTextHead->size.cy;
					pThisLine->vtLineSegment.push_back(pLineSegment3);
					pThisLine->nWidth = 0;
					pThisLine->nHeight = 0;
					
					nMaxHeight = pTextHead->size.cy;
					m_vtLine.push_back(pThisLine);
				}

				nCurrentLineWidth = nRemainWidth;
			}
			else
			{
				XMLSTATICLINESEGMENT *pLineSegment = new XMLSTATICLINESEGMENT;
				pLineSegment->pTextHead = pTextHead;
				pLineSegment->lpString = pTextHead->strText.c_str();
				pLineSegment->nStringWidth = pTextHead->strText.length();
				pLineSegment->nStringPosInTextHead = 0;
				pLineSegment->nWidth = pTextHead->size.cx;
				pLineSegment->nHeight = pTextHead->size.cy;
				
				if (pThisLine == NULL)
				{
					pThisLine = new XMLSTATICLINE;
					pThisLine->nWidth = 0;
					pThisLine->nHeight = 0;
					m_vtLine.push_back(pThisLine);
				}
				
				pThisLine->vtLineSegment.push_back(pLineSegment);
			}
		}
	}
	
	if (pThisLine->nHeight == 0)
		pThisLine->nHeight = nMaxHeight;

	delete pXmlDoc;
}