+    if (m_font.Ok())
+        wxGetTextExtent (m_display, m_font, m_userScaleY * m_logicalScaleY,
+                         text, &cx, &cy, &ascent, NULL);
+
+    wxBitmap src(cx, cy);
+    wxMemoryDC dc;
+    dc.SelectObject(src);
+    dc.SetFont(GetFont());
+    dc.SetBackground(*wxWHITE_BRUSH);
+    dc.SetBrush(*wxBLACK_BRUSH);
+    dc.Clear();
+    dc.DrawText(text, 0, 0);
+    dc.SetFont(wxNullFont);
+
+    // Calculate the size of the rotated bounding box.
+    double dx = cos(angle / 180.0 * M_PI);
+    double dy = sin(angle / 180.0 * M_PI);
+    double x4 = cy * dy;
+    double y4 = cy * dx;
+    double x3 = cx * dx;
+    double y3 = -cx * dy;
+    double x2 = x3 + x4;
+    double y2 = y3 + y4;
+    double x1 = x;
+    double y1 = y;
+
+    // Create image from the source bitmap after writing the text into it.
+    wxImage  image = src.ConvertToImage();
+
+    int minx = roundmin(0, roundmin(x4, roundmin(x2, x3)));
+    int miny = roundmin(0, roundmin(y4, roundmin(y2, y3)));
+    int maxx = roundmax(0, roundmax(x4, roundmax(x2, x3)));
+    int maxy = roundmax(0, roundmax(y4, roundmax(y2, y3)));
+
+    bool lastFore = false, lastBack = false;
+
+    // This rotates counterclockwise around the top left corner.
+    for (int rx = minx; rx < maxx; rx++)
+    {
+        for (int ry = miny; ry < maxy; ry++)
+        {
+            // transform dest coords to source coords
+            int sx = (int) (rx * dx - ry * dy + 0.5);
+            int sy = - (int) (-ry * dx - rx * dy + 0.5);
+            if (sx >= 0 && sx < cx && sy >= 0 && sy < cy)
+            {
+                bool textPixel = image.GetRed(sx, sy) == 0;
+
+                if (!textPixel && m_backgroundMode != wxSOLID)
+                    continue;
+
+                wxCoord ox = (wxCoord) (x1 + rx),
+                        oy = (wxCoord) (y1 + ry);
+                // draw black pixels, ignore white ones (i.e. transparent b/g)
+                if (textPixel && !lastFore)
+                {
+                    XSetForeground ((Display*) m_display, (GC) m_gc,
+                                    foregroundPixel);
+                    lastFore = true;
+                    lastBack = false;
+                }
+                else if (!textPixel && !lastBack)
+                {
+                    XSetForeground ((Display*) m_display, (GC) m_gc,
+                                    backgroundPixel);
+                    lastFore = false;
+                    lastBack = true;
+                }
+
+                XDrawPoint ((Display*) m_display, (Pixmap) m_pixmap,
+                            (GC) m_gc, XLOG2DEV (ox), YLOG2DEV (oy));
+                if (m_window && m_window->GetBackingPixmap())
+                    XDrawPoint ((Display*) m_display,
+                                (Pixmap) m_window->GetBackingPixmap(),
+                                (GC) m_gcBacking,
+                                XLOG2DEV_2 (ox), YLOG2DEV_2 (oy));
+            }
+        }
+    }
+
+    if (oldBackgroundPixel > -1)
+    {
+        XSetBackground ((Display*) m_display, (GC) m_gc, oldBackgroundPixel);
+        if (m_window && m_window->GetBackingPixmap())
+            XSetBackground ((Display*) m_display,(GC) m_gcBacking,
+                            oldBackgroundPixel);
+    }
+    if (oldForegroundPixel > -1)
+    {
+        XSetForeground ((Display*) m_display, (GC) m_gc, oldForegroundPixel);
+        if (m_window && m_window->GetBackingPixmap())
+            XSetForeground ((Display*) m_display,(GC) m_gcBacking,
+                            oldForegroundPixel);
+    }
+
+    CalcBoundingBox (minx, miny);
+    CalcBoundingBox (maxx, maxy);
+}
+
+bool wxWindowDC::CanGetTextExtent() const