TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFragment& fragment) const { ASSERT(style); ASSERT(textRenderer()); RenderText* text = textRenderer(); ASSERT(text); TextRun run(text->characters() + fragment.characterOffset , fragment.length , false /* allowTabs */ , 0 /* xPos, only relevant with allowTabs=true */ , 0 /* padding, only relevant for justified text, not relevant for SVG */ , TextRun::AllowTrailingExpansion , direction() , m_dirOverride || style->rtlOrdering() == VisualOrder /* directionalOverride */); if (textRunNeedsRenderingContext(style->font())) run.setRenderingContext(SVGTextRunRenderingContext::create(text)); run.disableRoundingHacks(); // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(text->textLength() - fragment.characterOffset); ASSERT(run.charactersLength() >= run.length()); return run; }
TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFragment& fragment) const { ASSERT(style); ASSERT(textRenderer()); RenderText* text = textRenderer(); ASSERT(text); TextRun run(text->characters() + fragment.positionListOffset , fragment.length , false /* allowTabs */ , 0 /* xPos, only relevant with allowTabs=true */ , 0 /* padding, only relevant for justified text, not relevant for SVG */ , TextRun::AllowTrailingExpansion , direction() == RTL , m_dirOverride || style->visuallyOrdered() /* directionalOverride */); #if ENABLE(SVG_FONTS) RenderObject* parentRenderer = parent()->renderer(); ASSERT(parentRenderer); run.setReferencingRenderObject(parentRenderer); #endif // Disable any word/character rounding. run.disableRoundingHacks(); // We handle letter & word spacing ourselves. run.disableSpacing(); return run; }
void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment) { if (textRenderer()->style()->textDecorationsInEffect() == TextDecorationNone) return; // Find out which render style defined the text-decoration, as its fill/stroke properties have to be used for drawing instead of ours. RenderObject* decorationRenderer = findRenderObjectDefininingTextDecoration(parent()); RenderStyle* decorationStyle = decorationRenderer->style(); ASSERT(decorationStyle); if (decorationStyle->visibility() == HIDDEN) return; const SVGRenderStyle* svgDecorationStyle = decorationStyle->svgStyle(); ASSERT(svgDecorationStyle); bool hasDecorationFill = svgDecorationStyle->hasFill(); bool hasVisibleDecorationStroke = svgDecorationStyle->hasVisibleStroke(); if (hasDecorationFill) { m_paintingResourceMode = ApplyToFillMode; paintDecorationWithStyle(context, decoration, fragment, decorationRenderer); } if (hasVisibleDecorationStroke) { m_paintingResourceMode = ApplyToStrokeMode; paintDecorationWithStyle(context, decoration, fragment, decorationRenderer); } }
QPixmap TextStyleToPixmap(const MapTextStyleConfig &config, const QColor &bgColor, uint overrideSize) { // generate string to render QString weightLabel; switch (config.weight) { case MapTextStyleConfig::Regular: weightLabel = ""; break; case MapTextStyleConfig::Bold: weightLabel = "/b"; break; case MapTextStyleConfig::Italic: weightLabel = "/i"; break; case MapTextStyleConfig::BoldItalic: weightLabel = "/bi"; break; } QString text = QString("%1/%2%3") .arg(config.font) .arg(config.size) .arg(weightLabel); MapTextStyleConfig configCopy = config; if (overrideSize) { configCopy.size = overrideSize; } maprender::TextRenderer textRenderer(configCopy, false, true); // figure out how big of a pixmap we need and where we want to draw the text SkScalar textWidth = 0; SkScalar textAscent = 0; SkScalar textDescent = 0; textWidth = textRenderer.MeasureText(text, &textAscent, &textDescent); textAscent = -textAscent; SkScalar margin = 1; SkScalar pixelWidth = textWidth + margin * 2; SkScalar pixelHeight = textAscent + textDescent + margin * 2; SkScalar posX = margin; SkScalar posY = margin + textAscent; // create the SkCanvas QImage qimage(int(pixelWidth), int(pixelHeight), 32); // qimage.setAlphaBuffer(true); qimage.fill(bgColor.rgb()); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, uint(pixelWidth), uint(pixelHeight)); bitmap.setPixels(qimage.bits()); SkCanvas canvas(bitmap); // render the preview into a canvas textRenderer.DrawText(canvas, text, posX, posY); // convert to a QPixmap return QPixmap(qimage); }
LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPosition) { int boxStart = start(); startPosition = max(startPosition - boxStart, 0); endPosition = min(endPosition - boxStart, static_cast<int>(len())); if (startPosition >= endPosition) return LayoutRect(); RenderStyle* style = textRenderer().style(); ASSERT(style); AffineTransform fragmentTransform; FloatRect selectionRect; int fragmentStartPosition = 0; int fragmentEndPosition = 0; unsigned textFragmentsSize = m_textFragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { const SVGTextFragment& fragment = m_textFragments.at(i); fragmentStartPosition = startPosition; fragmentEndPosition = endPosition; if (!mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) continue; FloatRect fragmentRect = selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style); fragment.buildFragmentTransform(fragmentTransform); if (!fragmentTransform.isIdentity()) fragmentRect = fragmentTransform.mapRect(fragmentRect); selectionRect.unite(fragmentRect); } return enclosingIntRect(selectionRect); }
bool Renderable::BuildBitmap(Displayer* displayer, DanmakuConfig* config) { if (!HasTextLayout()) return false; ComPtr<ID2D1Factory1> d2dFactory = displayer->GetD2DFactory(); if (nullptr == d2dFactory) return false; ComPtr<ID2D1Bitmap1> bmp = displayer->CreateBitmap( static_cast<uint32_t>(mDanmaku->mTextWidth), static_cast<uint32_t>(mDanmaku->mTextHeight) ); if (bmp == nullptr) return false; float strokeWidth = 1.5f * config->FontScaleFactor; strokeWidth *= displayer->GetDpiY() / 96.0f; ComPtr<ID2D1DeviceContext> deviceContext = displayer->AcquireDeviceContext(bmp); if (deviceContext == nullptr) return false; deviceContext->BeginDraw(); deviceContext->Clear(); deviceContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); ComPtr<ID2D1SolidColorBrush> brush; deviceContext->CreateSolidColorBrush(D2D1::ColorF(mDanmaku->mTextColor), &brush); ComPtr<ID2D1SolidColorBrush> outlineBrush; deviceContext->CreateSolidColorBrush(D2D1::ColorF(mDanmaku->mTextShadowColor, 1.0f), &outlineBrush); switch (config->DanmakuStyle) { case kOutline: { ComPtr<OutlineTextRenderer> textRenderer(new OutlineTextRenderer(d2dFactory, deviceContext, outlineBrush, strokeWidth, brush)); mTextLayout->Draw(deviceContext.Get(), textRenderer.Get(), 0.0f, 0.0f); break; } case kProjection: { deviceContext->DrawTextLayout(D2D1::Point2F(1.0f, 1.0f), mTextLayout.Get(), outlineBrush.Get()); deviceContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), mTextLayout.Get(), brush.Get()); break; } } HRESULT hr = deviceContext->EndDraw(); displayer->ReleaseDeviceContext(deviceContext); if (FAILED(hr)) return false; mBitmap = bmp; mBitmapValidFlag = config->BitmapValidFlag; return true; }
std::string GetName(ResourceManager &resourceManager) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); std::string name(""); std::vector<std::string> strVec{"Name: ", name}; TextRenderer textRenderer(resourceManager.GetTexture("text.png")); textRenderer.AddTextHorizontalAlign(strVec, TextRenderer::Alignment::Center, TextRenderer::Alignment::Center, 30, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); bool playing(true); glfwSetKeyCallback(glfwGetCurrentContext(), GetInput); bool enterPressed(false); while(playing && !glfwWindowShouldClose(glfwGetCurrentContext())) { glClear(GL_COLOR_BUFFER_BIT); name = Input(strVec.back()); if(name != strVec.back()) { textRenderer.RemoveText(strVec.back()); strVec.back() = name; textRenderer.AddTextHorizontalAlign(strVec, TextRenderer::Alignment::Center, TextRenderer::Alignment::Center, 30, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); } if(glfwGetKey(glfwGetCurrentContext(), GLFW_KEY_ENTER) == GLFW_PRESS && !enterPressed) { enterPressed = true; } else if(glfwGetKey(glfwGetCurrentContext(), GLFW_KEY_ENTER) == GLFW_RELEASE && enterPressed) { playing = false; if(strVec.back().empty()) { strVec.back() = "Player"; } } textRenderer.DrawAll(); glfwSwapBuffers(glfwGetCurrentContext()); glfwPollEvents(); } return name; }
TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFragment& fragment) const { ASSERT(style); ASSERT(textRenderer()); RenderText* text = textRenderer(); ASSERT(text); // FIXME(crbug.com/264211): This should not be necessary but can occur if we // layout during layout. Remove this when 264211 is fixed. RELEASE_ASSERT(!text->needsLayout()); TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero. , 0 // length, will be set below if non-zero. , 0 // xPos, only relevant with allowTabs=true , 0 // padding, only relevant for justified text, not relevant for SVG , TextRun::AllowTrailingExpansion , direction() , dirOverride() || style->rtlOrdering() == VisualOrder /* directionalOverride */); if (fragment.length) { if (text->is8Bit()) run.setText(text->characters8() + fragment.characterOffset, fragment.length); else run.setText(text->characters16() + fragment.characterOffset, fragment.length); } if (textRunNeedsRenderingContext(style->font())) run.setRenderingContext(SVGTextRunRenderingContext::create(text)); run.disableRoundingHacks(); // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(text->textLength() - fragment.characterOffset); ASSERT(run.charactersLength() >= run.length()); return run; }
void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, const CPos &pos, const float &z, const CRect &clipping) { CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); tech->BeginPass(); bool isClipped = (clipping != CRect()); if (isClipped) { glEnable(GL_SCISSOR_TEST); glScissor(clipping.left, g_yres - clipping.bottom, clipping.GetWidth(), clipping.GetHeight()); } CTextRenderer textRenderer(tech->GetShader()); textRenderer.SetClippingRect(clipping); textRenderer.Translate(0.0f, 0.0f, z); for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin(); it != Text.m_TextCalls.end(); ++it) { // If this is just a placeholder for a sprite call, continue if (it->m_pSpriteCall) continue; CColor color = it->m_UseCustomColor ? it->m_Color : DefaultColor; textRenderer.Color(color); textRenderer.Font(it->m_Font); textRenderer.Put((float)(int)(pos.x+it->m_Pos.x), (float)(int)(pos.y+it->m_Pos.y), &it->m_String); } textRenderer.Render(); for (std::list<SGUIText::SSpriteCall>::iterator it=Text.m_SpriteCalls.begin(); it!=Text.m_SpriteCalls.end(); ++it) { DrawSprite(it->m_Sprite, it->m_CellID, z, it->m_Area + pos); } if (isClipped) glDisable(GL_SCISSOR_TEST); tech->EndPass(); }
void CGUI::DrawText(SGUIText& Text, const CColor& DefaultColor, const CPos& pos, const float& z, const CRect& clipping) { CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); tech->BeginPass(); bool isClipped = (clipping != CRect()); if (isClipped) { glEnable(GL_SCISSOR_TEST); glScissor( clipping.left / g_GuiScale, g_yres - clipping.bottom / g_GuiScale, clipping.GetWidth() / g_GuiScale, clipping.GetHeight() / g_GuiScale); } CTextRenderer textRenderer(tech->GetShader()); textRenderer.SetClippingRect(clipping); textRenderer.Translate(0.0f, 0.0f, z); for (const SGUIText::STextCall& tc : Text.m_TextCalls) { // If this is just a placeholder for a sprite call, continue if (tc.m_pSpriteCall) continue; CColor color = tc.m_UseCustomColor ? tc.m_Color : DefaultColor; textRenderer.Color(color); textRenderer.Font(tc.m_Font); textRenderer.Put((float)(int)(pos.x + tc.m_Pos.x), (float)(int)(pos.y + tc.m_Pos.y), &tc.m_String); } textRenderer.Render(); for (const SGUIText::SSpriteCall& sc : Text.m_SpriteCalls) DrawSprite(sc.m_Sprite, sc.m_CellID, z, sc.m_Area + pos); if (isClipped) glDisable(GL_SCISSOR_TEST); tech->EndPass(); }
void TerrainRenderer::RenderPriorities() { PROFILE("priorities"); ENSURE(m->phase == Phase_Render); CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); tech->BeginPass(); CTextRenderer textRenderer(tech->GetShader()); textRenderer.Font(L"mono-stroke-10"); textRenderer.Color(1.0f, 1.0f, 0.0f); for (size_t i = 0; i < m->visiblePatches.size(); ++i) m->visiblePatches[i]->RenderPriorities(textRenderer); textRenderer.Render(); tech->EndPass(); }
//Render Manager. void CConsole::Render() { if (! (m_bVisible || m_bToggle) ) return; PROFILE3_GPU("console"); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); solidTech->BeginPass(); CShaderProgramPtr solidShader = solidTech->GetShader(); CMatrix3D transform = GetDefaultGuiMatrix(); // animation: slide in from top of screen const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight; transform.PostTranslate(m_fX, m_fY - DeltaY, 0.0f); // move to window position solidShader->Uniform(str_transform, transform); DrawWindow(solidShader); solidTech->EndPass(); CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); textTech->BeginPass(); CTextRenderer textRenderer(textTech->GetShader()); textRenderer.Font(CStrIntern(CONSOLE_FONT)); textRenderer.SetTransform(transform); DrawHistory(textRenderer); DrawBuffer(textRenderer); textRenderer.Render(); textTech->EndPass(); glDisable(GL_BLEND); }
void DisplayHighscores(ResourceManager &resourceManager) { TextRenderer textRenderer(resourceManager.GetTexture("text.png")); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); textRenderer.AddText("Press Enter To Return To The Main Menu", TextRenderer::Alignment::Center, TextRenderer::Alignment::Bottom, 20, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); std::vector<std::string> strVec{"Highscores:"}; if(AddAllTextToHighscores(strVec)) { textRenderer.AddTextVerticalAlign(strVec, TextRenderer::Alignment::Center, TextRenderer::Alignment::Center, 30, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); bool enterPressed(false); for(bool playing(true); playing && !glfwWindowShouldClose(glfwGetCurrentContext());) { while(!glfwWindowShouldClose(glfwGetCurrentContext()) && playing) { glClear(GL_COLOR_BUFFER_BIT); if(glfwGetKey(glfwGetCurrentContext(), GLFW_KEY_ENTER) == GLFW_PRESS && !enterPressed) enterPressed = true; else if(glfwGetKey(glfwGetCurrentContext(), GLFW_KEY_ENTER) == GLFW_RELEASE && enterPressed) playing = false; textRenderer.DrawAll(); glfwSwapBuffers(glfwGetCurrentContext()); glfwPollEvents(); } } } return; }
// Render void CProfileViewer::RenderProfile() { if (!m->profileVisible) return; if (!m->path.size()) { m->profileVisible = false; return; } PROFILE3_GPU("profile viewer"); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); AbstractProfileTable* table = m->path[m->path.size() - 1]; const std::vector<ProfileColumn>& columns = table->GetColumns(); size_t numrows = table->GetNumberRows(); CStrIntern font_name("mono-stroke-10"); CFontMetrics font(font_name); int lineSpacing = font.GetLineSpacing(); // Render background GLint estimate_height; GLint estimate_width; estimate_width = 50; for(size_t i = 0; i < columns.size(); ++i) estimate_width += (GLint)columns[i].width; estimate_height = 3 + (GLint)numrows; if (m->path.size() > 1) estimate_height += 2; estimate_height = lineSpacing*estimate_height; CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); solidTech->BeginPass(); CShaderProgramPtr solidShader = solidTech->GetShader(); solidShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.5f); CMatrix3D transform = GetDefaultGuiMatrix(); solidShader->Uniform(str_transform, transform); float backgroundVerts[] = { (float)estimate_width, 0.0f, 0.0f, 0.0f, 0.0f, (float)estimate_height, 0.0f, (float)estimate_height, (float)estimate_width, (float)estimate_height, (float)estimate_width, 0.0f }; solidShader->VertexPointer(2, GL_FLOAT, 0, backgroundVerts); solidShader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); transform.PostTranslate(22.0f, lineSpacing*3.0f, 0.0f); solidShader->Uniform(str_transform, transform); // Draw row backgrounds for (size_t row = 0; row < numrows; ++row) { if (row % 2) solidShader->Uniform(str_color, 1.0f, 1.0f, 1.0f, 0.1f); else solidShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.1f); float rowVerts[] = { -22.f, 2.f, estimate_width-22.f, 2.f, estimate_width-22.f, 2.f-lineSpacing, estimate_width-22.f, 2.f-lineSpacing, -22.f, 2.f-lineSpacing, -22.f, 2.f }; solidShader->VertexPointer(2, GL_FLOAT, 0, rowVerts); solidShader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); transform.PostTranslate(0.0f, lineSpacing, 0.0f); solidShader->Uniform(str_transform, transform); } solidTech->EndPass(); // Print table and column titles CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); textTech->BeginPass(); CTextRenderer textRenderer(textTech->GetShader()); textRenderer.Font(font_name); textRenderer.Color(1.0f, 1.0f, 1.0f); textRenderer.PrintfAt(2.0f, lineSpacing, L"%hs", table->GetTitle().c_str()); textRenderer.Translate(22.0f, lineSpacing*2.0f, 0.0f); float colX = 0.0f; for (size_t col = 0; col < columns.size(); ++col) { CStrW text = columns[col].title.FromUTF8(); int w, h; font.CalculateStringSize(text.c_str(), w, h); float x = colX; if (col > 0) // right-align all but the first column x += columns[col].width - w; textRenderer.Put(x, 0.0f, text.c_str()); colX += columns[col].width; } textRenderer.Translate(0.0f, lineSpacing, 0.0f); // Print rows int currentExpandId = 1; for (size_t row = 0; row < numrows; ++row) { if (table->IsHighlightRow(row)) textRenderer.Color(1.0f, 0.5f, 0.5f); else textRenderer.Color(1.0f, 1.0f, 1.0f); if (table->GetChild(row)) { textRenderer.PrintfAt(-15.0f, 0.0f, L"%d", currentExpandId); currentExpandId++; } float colX = 0.0f; for (size_t col = 0; col < columns.size(); ++col) { CStrW text = table->GetCellText(row, col).FromUTF8(); int w, h; font.CalculateStringSize(text.c_str(), w, h); float x = colX; if (col > 0) // right-align all but the first column x += columns[col].width - w; textRenderer.Put(x, 0.0f, text.c_str()); colX += columns[col].width; } textRenderer.Translate(0.0f, lineSpacing, 0.0f); } textRenderer.Color(1.0f, 1.0f, 1.0f); if (m->path.size() > 1) { textRenderer.Translate(0.0f, lineSpacing, 0.0f); textRenderer.Put(-15.0f, 0.0f, L"0"); textRenderer.Put(0.0f, 0.0f, L"back to parent"); } textRenderer.Render(); textTech->EndPass(); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); }