Exemple #1
0
/**
 * Checks if given dash pattern is already set in PDF gstate and if not,
 * update the gstate accordingly.
 * \param page	PDF page where the update needs to happen.
 * \param dash	Wanted dash pattern.
 */
void pdfw_gs_dash(HPDF_Page page, DashPattern_e dash)
{
	if (dash == pdfw_gs[pdfw_gs_level].dash)
		return;
	pdfw_gs[pdfw_gs_level].dash = dash;
	switch (dash) {
		case DashPattern_eNone: {
			HPDF_Page_SetDash(page, NULL, 0, 0);
			break;
		}
		case DashPattern_eDash: {
			const HPDF_UINT16 dash_ptn[] = {3};
			HPDF_Page_SetDash(page, dash_ptn, 1, 1);
			break;
		}
		case DashPattern_eDotted: {
			const HPDF_UINT16 dash_ptn[] = {1};
			HPDF_Page_SetDash(page, dash_ptn, 1, 1);
			break;
		}
	}
}
Exemple #2
0
void WPdfImage::setChanged(WFlags<PainterChangeFlag> flags)
{
  if (!flags.empty()) {
    HPDF_Page_GRestore(page_);
    HPDF_Page_GSave(page_);

    HPDF_ExtGState gstate;
    gstate = HPDF_CreateExtGState (pdf_);

    currentFont_ = WFont();

    if (painter()->hasClipping()) {
      const WTransform& t = painter()->clipPathTransform();

      if (!painter()->clipPath().isEmpty()) {
        applyTransform(t);

        drawPlainPath(painter()->clipPath());
        HPDF_Page_Clip(page_);
        HPDF_Page_EndPath(page_);

        applyTransform(t.inverted());
      }
    }

    applyTransform(painter()->combinedTransform());

    const WPen& pen = painter()->pen();

    if (pen.style() != PenStyle::None) {
      const WColor& color = pen.color();

      HPDF_Page_SetRGBStroke(page_,
                             color.red() / 255.,
                             color.green() / 255.,
                             color.blue() / 255.);

      HPDF_ExtGState_SetAlphaStroke (gstate, color.alpha()/255.);

      WLength w = painter()->normalizedPenWidth(pen.width(), false);
      HPDF_Page_SetLineWidth(page_, w.toPixels());

      switch (pen.capStyle()) {
      case PenCapStyle::Flat:
	HPDF_Page_SetLineCap(page_, HPDF_BUTT_END);
	break;
      case PenCapStyle::Square:
	HPDF_Page_SetLineCap(page_, HPDF_PROJECTING_SCUARE_END); // scuary !
	break;
      case PenCapStyle::Round:
	HPDF_Page_SetLineCap(page_, HPDF_ROUND_END);
	break;
      }

      switch (pen.joinStyle()) {
      case PenJoinStyle::Miter:
	HPDF_Page_SetLineJoin(page_, HPDF_MITER_JOIN);
	break;
      case PenJoinStyle::Bevel:
	HPDF_Page_SetLineJoin(page_, HPDF_BEVEL_JOIN);
	break;
      case PenJoinStyle::Round:
	HPDF_Page_SetLineJoin(page_, HPDF_ROUND_JOIN);
	break;
      }

      switch (pen.style()) {
      case PenStyle::None:
	break;
      case PenStyle::SolidLine:
	HPDF_Page_SetDash(page_, nullptr, 0, 0);
	break;
      case PenStyle::DashLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
	break;
      }
      case PenStyle::DotLine: {
	const HPDF_UINT16 dash_ptn[] = { 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
	break;
      }
      case PenStyle::DashDotLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2, 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 4, 0);
	break;
      }
      case PenStyle::DashDotDotLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2, 1, 2, 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 6, 0);
	break;
      }
      }
    }

    const WBrush& brush = painter()->brush();

    if (brush.style() != BrushStyle::None) {
      const WColor& color = painter()->brush().color();

      HPDF_Page_SetRGBFill(page_,
                           color.red() / 255.,
                           color.green() / 255.,
                           color.blue() / 255.);

      HPDF_ExtGState_SetAlphaFill (gstate, color.alpha()/255.);
    }

    HPDF_Page_SetExtGState (page_, gstate);

    

    const WFont& font = painter()->font();

    if (font == currentFont_ && !trueTypeFonts_->busy())
      return;

    /*
     * First, try a true type font.
     */
    std::string ttfFont;
    if (trueTypeFonts_->busy()) {
      /*
       * We have a resolved true type font.
       */
      ttfFont = trueTypeFonts_->drawingFontPath();
    } else {
      FontSupport::FontMatch match = trueTypeFonts_->matchFont(font);

      if (match.matched())
	ttfFont = match.fileName();
    }

    LOG_DEBUG("font: " << ttfFont);

    if (font == currentFont_ &&
        !ttfFont.empty() &&
        currentTtfFont_ == ttfFont)
      return;

    currentFont_ = font;

    const char *font_name = nullptr;
    font_ = nullptr;

    if (!ttfFont.empty()) {

      bool fontOk = false;

      std::map<std::string, const char *>::const_iterator i
	= ttfFonts_.find(ttfFont);

      if (i != ttfFonts_.end()) {
	font_name = i->second;
	fontOk = true;
      } else if (ttfFont.length() > 4) {
	std::string suffix
	  = Utils::lowerCase(ttfFont.substr(ttfFont.length() - 4));

	if (suffix == ".ttf") {
	  font_name = HPDF_LoadTTFontFromFile (pdf_, ttfFont.c_str(),
					       HPDF_TRUE);
	} else if (suffix == ".ttc") {
	  /* Oops, pango didn't tell us which font to load ... */
	  font_name = HPDF_LoadTTFontFromFile2(pdf_, ttfFont.c_str(),
					       0, HPDF_TRUE);
	}

	if (!font_name)
	  HPDF_ResetError (pdf_);
	else {
	  ttfFonts_[ttfFont] = font_name;
	  fontOk = true;
	}
      }

      if (!fontOk)
	LOG_ERROR("cannot read font: '" << ttfFont << "': "
		  "expecting a true type font (.ttf, .ttc)");
    }

    if (!font_ && font_name) {
      font_ = HPDF_GetFont (pdf_, font_name, "UTF-8");

      if (!font_)
	HPDF_ResetError (pdf_);
      else {
	trueTypeFont_ = true;
        currentTtfFont_ = ttfFont;
      }
    }

    if (!font_) {
      trueTypeFont_ = false;
      currentTtfFont_.clear();

      std::string name = Pdf::toBase14Font(font);
      font_ = HPDF_GetFont(pdf_, name.c_str(), nullptr);
    }

    fontSize_ = font.sizeLength(12).toPixels();

    HPDF_Page_SetFontAndSize (page_, font_, fontSize_);
  }
}