code: private void renderTextPath(SVG.TextPath obj)
     {
        debug("TextPath render");
  
        updateStyleForElement(state, obj);
  
        if (!display())
           return;
        if (!visible())
           return;
  
        SVG.SvgObject  ref = obj.document.resolveIRI(obj.href);
        if (ref == null)
        {
           error("TextPath reference '%s' not found", obj.href);
           return;
        }
  
        SVG.Path     pathObj = (SVG.Path) ref;
        Path         path = (new PathConverter(pathObj.d)).getPath();
  
        if (pathObj.transform != null)
           path.transform(pathObj.transform);
  
        PathMeasure  measure = new PathMeasure(path, false);
  
        float  startOffset = (obj.startOffset != null) ? obj.startOffset.floatValue(this, measure.getLength()) : 0f;
  
        // Handle text alignment
        Style.TextAnchor  anchor = getAnchorPosition();
        if (anchor != Style.TextAnchor.Start) {
           float  textWidth = calculateTextWidth(obj);
           if (anchor == Style.TextAnchor.Middle) {
              startOffset -= (textWidth / 2);
           } else {
              startOffset -= textWidth;  // 'End' (right justify)
           }
        }
  
        checkForGradientsAndPatterns((SvgElement) obj.getTextRoot());
        
        boolean  compositing = pushLayer();
  
        enumerateTextSpans(obj, new PathTextDrawer(path, startOffset, 0f));
  
        if (compositing)
           popLayer(obj);
     }
docs: ==============================================================================