public BufferedImage convert(
      final DecoderResults resultsFromDecode,
      final int displayRotation,
      final PdfResources res,
      final ExternalHandlers externalHandlers,
      final int renderMode,
      final PdfPageData pageData,
      final AcroRenderer formRenderer,
      final float scaling,
      final PdfObjectReader currentPdfFile,
      final int pageIndex,
      final boolean imageIsTransparent,
      final String currentPageOffset)
      throws PdfException {

    final ObjectStore localStore = new ObjectStore();

    /** read page or next pages */
    final PdfObject pdfObject = new PageObject(currentPageOffset);
    currentPdfFile.readObject(pdfObject);

    currentPdfFile.checkParentForResources(pdfObject);

    // ensure set (needed for XFA)
    pdfObject.setPageNumber(pageIndex);

    final PdfObject Resources = pdfObject.getDictionary(PdfDictionary.Resources);

    imageDisplay = getDisplay(pageIndex, localStore, imageIsTransparent);

    if (!imageDisplay.isHTMLorSVG()) {

      if (options.getPageColor() != null) {
        imageDisplay.setValue(
            DynamicVectorRenderer.ALT_BACKGROUND_COLOR, options.getPageColor().getRGB());
      }

      if (options.getTextColor() != null) {
        imageDisplay.setValue(
            DynamicVectorRenderer.ALT_FOREGROUND_COLOR, options.getTextColor().getRGB());

        if (options.getChangeTextAndLine()) {
          imageDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 1);
        } else {
          imageDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 0);
        }

        imageDisplay.setValue(
            DynamicVectorRenderer.COLOR_REPLACEMENT_THRESHOLD,
            options.getReplacementColorThreshold());
      }
    }

    final PdfStreamDecoder currentImageDecoder =
        formRenderer.getStreamDecoder(currentPdfFile, true, null, true);

    currentImageDecoder.setParameters(
        true,
        true,
        renderMode,
        PdfDecoderInt.TEXT,
        false,
        externalHandlers.getMode().equals(GUIModes.JAVAFX));

    externalHandlers.addHandlers(currentImageDecoder);

    // currentImageDecoder.setObjectValue(ValueTypes.Name, filename);
    currentImageDecoder.setObjectValue(ValueTypes.ObjectStore, localStore);
    currentImageDecoder.setMultiplyer(multiplyer);
    currentImageDecoder.setObjectValue(ValueTypes.PDFPageData, pageData);
    currentImageDecoder.setIntValue(ValueTypes.PageNum, pageIndex);

    currentImageDecoder.setRenderer(imageDisplay);
    externalHandlers.addHandlers(currentImageDecoder);

    res.setupResources(currentImageDecoder, true, Resources, pageIndex, currentPdfFile);

    // can for max
    if (multiplyer == -2) {

      multiplyer = -1;
      currentImageDecoder.setMultiplyer(multiplyer);

      final PdfStreamDecoderForSampling currentImageDecoder2 =
          new PdfStreamDecoderForSampling(currentPdfFile);
      currentImageDecoder2.setParameters(
          true, true, renderMode, 0, false, externalHandlers.getMode().equals(GUIModes.JAVAFX));

      // currentImageDecoder2.setObjectValue(ValueTypes.Name, filename);
      currentImageDecoder2.setObjectValue(ValueTypes.ObjectStore, localStore);
      currentImageDecoder2.setMultiplyer(multiplyer);
      currentImageDecoder2.setObjectValue(ValueTypes.PDFPageData, pageData);
      currentImageDecoder2.setIntValue(ValueTypes.PageNum, pageIndex);
      currentImageDecoder2.setRenderer(imageDisplay);

      res.setupResources(currentImageDecoder2, true, Resources, pageIndex, currentPdfFile);

      externalHandlers.addHandlers(currentImageDecoder2);

      /** bare minimum to get value */
      multiplyer = currentImageDecoder2.decodePageContentForImageSampling(pdfObject);

      int bestQualityMaxScalingToUse = 0;
      if (instance_bestQualityMaxScaling != null) {
        bestQualityMaxScalingToUse = instance_bestQualityMaxScaling;
      } else if (bestQualityMaxScaling != null) {
        bestQualityMaxScalingToUse = bestQualityMaxScaling;
      }

      if (bestQualityMaxScalingToUse > 0 && multiplyer > bestQualityMaxScalingToUse) {
        multiplyer = bestQualityMaxScalingToUse;
      }

      currentImageDecoder2.setMultiplyer(multiplyer);
      currentImageDecoder.setMultiplyer(multiplyer);
    }

    if (!allowPagesSmallerThanPageSize
        && !instance_allowPagesSmallerThanPageSize
        && multiplyer < 1
        && multiplyer > 0) {
      multiplyer = 1;
    }

    // allow for value not set
    if (multiplyer == -1) {
      multiplyer = 1;
    }

    /** setup positions,transformations and image */
    imageScaling =
        PDFtoImageConvertorSwing.setPageParametersForImage(
            scaling * multiplyer, pageIndex, pageData);

    setParams(scaling, pageData, pageIndex);

    final BufferedImage image =
        pageToImage(imageIsTransparent, currentImageDecoder, scaling, pdfObject, formRenderer);

    resultsFromDecode.update(currentImageDecoder, false);

    /** draw acroform data onto Panel */
    if (formRenderer != null
        && formRenderer.hasFormsOnPage(pageIndex)
        && !formRenderer.ignoreForms()) {

      resultsFromDecode.resetColorSpaces();

      if (!formRenderer.getCompData().hasformsOnPageDecoded(pageIndex)) {
        formRenderer.createDisplayComponentsForPage(pageIndex, currentImageDecoder);
      }

      if (isFX) {
        // done in fx image code
      } else if (!formRenderer.getCompData().formsRasterizedForDisplay()) {

        if (!formRenderer.useXFA()) {

          java.util.List[] formsOrdered = formRenderer.getCompData().getFormList(true);

          // get unsorted components and iterate over forms
          for (Object nextVal : formsOrdered[pageIndex]) {

            if (nextVal != null) {
              formRenderer
                  .getFormFlattener()
                  .drawFlattenedForm(
                      currentImageDecoder,
                      (org.jpedal.objects.raw.FormObject) nextVal,
                      false,
                      (PdfObject) formRenderer.getFormResources()[0]);
            }
          }

        } else {
          formRenderer
              .getCompData()
              .renderFormsOntoG2(
                  image.getGraphics(),
                  pageIndex,
                  0,
                  displayRotation,
                  null,
                  null,
                  pageData.getMediaBoxHeight(pageIndex));
        }
      } else {

        final java.util.List[] formsOrdered = formRenderer.getCompData().getFormList(true);

        // get unsorted components and iterate over forms
        for (final Object nextVal : formsOrdered[pageIndex]) {

          if (nextVal != null) {

            formRenderer
                .getFormFlattener()
                .drawFlattenedForm(
                    currentImageDecoder,
                    (org.jpedal.objects.raw.FormObject) nextVal,
                    false,
                    (PdfObject) formRenderer.getFormResources()[0]);
          }
        }
      }
    }

    if (currentImageDecoder != null) {
      currentImageDecoder.dispose();
    }

    localStore.flush();
    return image;
  }
  static void renderTextWithJavaFonts(
      GraphicsState gs,
      DynamicVectorRenderer current,
      int streamType,
      ParserOptions parserOptions,
      PdfFont currentFontData,
      GlyphData glyphData,
      final int Tmode,
      final float currentWidth,
      final boolean isTextShifted,
      final PdfJavaGlyphs glyphs,
      final float[][] Trm) {

    final float actualWidth = glyphData.getActualWidth();

    /** set values used if rendering as well */
    Object transformedGlyph2;
    AffineTransform glyphAt = null;

    final int rawInt = glyphData.getRawInt();

    //
    { // render now
      final boolean isSTD =
          actualWidth > 0
              || DecoderOptions.isRunningOnMac
              || streamType == ValueTypes.FORM
              || StandardFonts.isStandardFont(currentFontData.getBaseFontName(), false)
              || currentFontData.isBrokenFont();

      /** flush cache if needed */
      // if(!DynamicVectorRenderer.newCode2){
      if (glyphs.lastTrm[0][0] != Trm[0][0]
          || glyphs.lastTrm[1][0] != Trm[1][0]
          || glyphs.lastTrm[0][1] != Trm[0][1]
          || glyphs.lastTrm[1][1] != Trm[1][1]) {
        glyphs.lastTrm = Trm;
        glyphs.flush();
      }
      // }

      // either calculate the glyph to draw or reuse if already drawn
      Area glyph = glyphs.getCachedShape(rawInt);
      glyphAt = glyphs.getCachedTransform(rawInt);

      if (glyph == null) {

        double dY = -1, dX = 1, x3 = 0, y3 = 0;

        // allow for text running up the page
        if ((Trm[1][0] < 0 && Trm[0][1] >= 0) || (Trm[0][1] < 0 && Trm[1][0] >= 0)) {
          dX = 1f;
          dY = -1f;
        }

        if (isSTD) {

          glyph = glyphs.getGlyph(rawInt, glyphData.getDisplayValue(), currentWidth);

          // hack to fix problem with Java Arial font
          if (glyph != null && rawInt == 146 && glyphs.isArialInstalledLocally) {
            y3 = -(glyph.getBounds().height - glyph.getBounds().y);
          }
        } else {

          // remap font if needed
          String xx = glyphData.getDisplayValue();

          GlyphVector gv1 = null;

          // do not show CID fonts as Lucida unless match
          if (!glyphs.isCIDFont || glyphs.isCorrupted() || glyphs.isFontInstalled) {
            gv1 = glyphs.getUnscaledFont().createGlyphVector(PdfJavaGlyphs.frc, xx);
          }

          if (gv1 != null) {

            glyph = new Area(gv1.getOutline());

            // put glyph into display position
            double glyphX = gv1.getOutline().getBounds2D().getX();

            // ensure inside box
            x3 = 0;

            if (glyphX < 0) {
              glyphX = -glyphX;

              x3 = glyphX * 2;

              // System.out.println(x3+" "+displayTrm[0][0]+" "+displayTrm[0][0]);

              if (Trm[0][0] > Trm[0][1]) {
                x3 *= Trm[0][0];
              } else {
                x3 *= Trm[0][1];
              }

              // glyphAt =AffineTransform.getTranslateInstance(x3,0);

            }

            final double glyphWidth = gv1.getVisualBounds().getWidth() + (glyphX * 2);
            final double scaleFactor = currentWidth / glyphWidth;
            if (scaleFactor < 1) {
              dX *= scaleFactor;
            }

            if (x3 > 0) {
              x3 *= dX;
            }
          }
        }

        glyphAt =
            new AffineTransform(
                dX * Trm[0][0], dX * Trm[0][1], dY * Trm[1][0], dY * Trm[1][1], x3, y3);
        // create shape for text using transformation to make correct size
        // glyphAt =new AffineTransform(dX* displayTrm[0][0],dX* displayTrm[0][1],dY*
        // displayTrm[1][0],dY* displayTrm[1][1] ,x3, y3);

        // save so we can reuse if it occurs again in this TJ command
        glyphs.setCachedShape(rawInt, glyph, glyphAt);
      }

      if (glyph != null && Tmode == GraphicsState.CLIPTEXT && glyph.getBounds().width > 0) {
          /** support for TR7 */

        final Area glyphShape = (Area) glyph.clone();

        // we need to apply to make it all work
        glyphShape.transform(glyphAt);

        // if its already generated we just need to move it
        if (parserOptions.renderDirectly()) {
          final AffineTransform at2 = AffineTransform.getTranslateInstance(Trm[2][0], (Trm[2][1]));
          glyphShape.transform(at2);
        }

        gs.addClip(glyphShape);

        // current.drawClip(gs,null,false);

        // if(parserOptions.renderDirectly()) {
        glyph = null;
        // }

      }

      transformedGlyph2 = glyph;
    }

    if (transformedGlyph2 != null) {

      final double[] textTrans = new double[6];
      glyphAt.getMatrix(textTrans);

      final int fontSize = glyphData.getFontSize();

      if (parserOptions.useJavaFX()) {
        current.drawEmbeddedText(
            Trm,
            fontSize,
            null,
            null,
            DynamicVectorRenderer.TEXT,
            gs,
            textTrans,
            glyphData.getUnicodeValue(),
            currentFontData,
            -100);
      } else

      // add to renderer
      if (parserOptions.renderDirectly()) {
        current.drawEmbeddedText(
            Trm,
            fontSize,
            null,
            transformedGlyph2,
            DynamicVectorRenderer.TEXT,
            gs,
            textTrans,
            glyphData.getUnicodeValue(),
            currentFontData,
            -100);
      } else {

        if (isTextShifted) {
          current.drawEmbeddedText(
              Trm,
              -fontSize,
              null,
              transformedGlyph2,
              DynamicVectorRenderer.TEXT,
              gs,
              null,
              glyphData.getUnicodeValue(),
              currentFontData,
              -100);
        } else {
          current.drawEmbeddedText(
              Trm,
              fontSize,
              null,
              transformedGlyph2,
              DynamicVectorRenderer.TEXT,
              gs,
              null,
              glyphData.getUnicodeValue(),
              currentFontData,
              -100);
        }
      }
    }
  }