title: Rendering text using D2D
body: <p>I have created a UI text component that will draw text onscreen in my game engine (UWP). However, I am experiencing problems with positioning due to resolution scale. On my laptop screen (resolution scale 2) it looks good, but on my external monitor (resolution scale of 1) the text is slightly offset.</p>
  
  <p>This is the UI text component rendering code:</p>
  
  <pre><code>void TextComponent::Render(shared_ptr&lt;AmberDevice&gt; device, ShaderConfiguration&amp; configuration)
  {
    auto context = m_device-&gt;GetProperties().GetD2DDeviceContext();
    context-&gt;SaveDrawingState(m_stateBlock.Get());
    context-&gt;BeginDraw();
  
    device-&gt;ApplyTextTransform(GetTransform());
  
    context-&gt;DrawTextLayout(
      Point2(0.0f, 0.0f),
      m_layout.Get(),
      m_brush.Get());
  
    context-&gt;EndDraw();
    context-&gt;RestoreDrawingState(m_stateBlock.Get());
  }
  </code></pre>
  
  <p>The ApplyTextTransform method looks like this (does the actual translation calculations):</p>
  
  <pre><code>void AmberDevice::ApplyTextTransform(Amber::Scene::Transform2D transform)
  {
    auto size = transform.GetSize();
    auto scaling = transform.GetScale();
    auto rotation = transform.GetRotation();
    auto translation = transform.GetPosition();
    auto pivot = transform.GetPivot();
    auto screenSize = m_properties.GetRenderOutputSize();
    auto scaleFactor = m_properties.GetResolutionScale();
  
    Matrix3x2F translate = Matrix3x2F::Translation(
      (translation.x / scaleFactor) + (screenSize.x / (scaleFactor * 2.f)),
     -(translation.y / scaleFactor) + (screenSize.y / (scaleFactor * 2.f)));
  
    Matrix3x2F scale = Matrix3x2F::Scale(Size(scaling.x, scaling.y), center);
    Matrix3x2F rotate = Matrix3x2F::Rotation(rotation, center);
  
    m_properties.GetD2DDeviceContext()-&gt;SetTransform(
      scale * rotate * translate * m_properties.GetOrientationTransform2D());
  }
  </code></pre>
  
  <p>I am dividing the screen size and component's position by the resolution scale to normalize them and get them in the same resolution as the logical resolution of the system (i.e. non-scaled). I add half the logical screen width and height to the final translation so I can get 0,0 in the center of the screen, to make it similar to the way sprites are drawn in the D3D orthogonal grid.</p>