HPDF_MarkupAnnot_SetRectDiff (HPDF_Annotation  annot, HPDF_Rect  rect) /* RD entry : this is the difference between Rect and the text annotation rectangle */
{
    HPDF_Array array;
    HPDF_STATUS ret = HPDF_OK;
    HPDF_REAL tmp;

    HPDF_PTRACE((" HPDF_MarkupAnnot_SetRectDiff\n"));

    array = HPDF_Array_New ( annot->mmgr);
    if ( !array)
        return HPDF_Error_GetCode ( annot->error);

    if ((ret = HPDF_Dict_Add ( annot, "RD", array)) != HPDF_OK)
        return ret;

    if (rect.top < rect.bottom) {
        tmp = rect.top;
        rect.top = rect.bottom;
        rect.bottom = tmp;
    }

    ret += HPDF_Array_AddReal (array, rect.left);
    ret += HPDF_Array_AddReal (array, rect.bottom);
    ret += HPDF_Array_AddReal (array, rect.right);
    ret += HPDF_Array_AddReal (array, rect.top);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode (array->error);

    return HPDF_OK;
}
HPDF_Destination_SetXYZ  (HPDF_Destination  dst,
                          HPDF_REAL         left,
                          HPDF_REAL         top,
                          HPDF_REAL         zoom)
{
    HPDF_STATUS ret = HPDF_OK;
    HPDF_Page target;

    HPDF_PTRACE((" HPDF_Destination_SetXYZ\n"));

    if (!HPDF_Destination_Validate (dst))
        return HPDF_INVALID_DESTINATION;

    if (left < 0 || top < 0 || zoom < 0.08 || zoom > 32)
        return HPDF_RaiseError (dst->error, HPDF_INVALID_PARAMETER, 0);


    target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);

    if (dst->list->count > 1) {
        HPDF_Array_Clear (dst);
        ret += HPDF_Array_Add (dst, target);
    }

    ret += HPDF_Array_AddName (dst,
                HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_XYZ]);
    ret += HPDF_Array_AddReal (dst, left);
    ret += HPDF_Array_AddReal (dst, top);
    ret += HPDF_Array_AddReal (dst, zoom);

    if (ret != HPDF_OK)
        return HPDF_CheckError (dst->error);

    return HPDF_OK;
}
HPDF_Destination_SetFitR  (HPDF_Destination  dst,
                           HPDF_REAL         left,
                           HPDF_REAL         bottom,
                           HPDF_REAL         right,
                           HPDF_REAL         top)
{
    HPDF_STATUS ret = HPDF_OK;
    HPDF_Page target;

    HPDF_PTRACE((" HPDF_Destination_SetFitR\n"));

    if (!HPDF_Destination_Validate (dst))
        return HPDF_INVALID_DESTINATION;

    target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);

    if (dst->list->count > 1) {
        HPDF_Array_Clear (dst);
        ret += HPDF_Array_Add (dst, target);
    }

    ret += HPDF_Array_AddName (dst,
                HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_R]);
    ret += HPDF_Array_AddReal (dst, left);
    ret += HPDF_Array_AddReal (dst, bottom);
    ret += HPDF_Array_AddReal (dst, right);
    ret += HPDF_Array_AddReal (dst, top);

    if (ret != HPDF_OK)
        return HPDF_CheckError (dst->error);

    return HPDF_OK;
}
HPDF_TextMarkupAnnot_SetQuadPoints ( HPDF_Annotation annot, HPDF_Point lb, HPDF_Point rb, HPDF_Point lt, HPDF_Point rt) /* l-left, r-right, b-bottom, t-top positions */
{
    HPDF_Array quadPoints;
    HPDF_STATUS ret = HPDF_OK;

    HPDF_PTRACE((" HPDF_TextMarkupAnnot_SetQuadPoints\n"));

    quadPoints = HPDF_Array_New ( annot->mmgr);
    if ( !quadPoints)
        return HPDF_Error_GetCode ( annot->error);

    if ((ret = HPDF_Dict_Add ( annot, "QuadPoints", quadPoints)) != HPDF_OK)
        return ret;

    ret += HPDF_Array_AddReal (quadPoints, lb.x);
    ret += HPDF_Array_AddReal (quadPoints, lb.y);
    ret += HPDF_Array_AddReal (quadPoints, rb.x);
    ret += HPDF_Array_AddReal (quadPoints, rb.y);
    ret += HPDF_Array_AddReal (quadPoints, lt.x);
    ret += HPDF_Array_AddReal (quadPoints, lt.y);
    ret += HPDF_Array_AddReal (quadPoints, rt.x);
    ret += HPDF_Array_AddReal (quadPoints, rt.y);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode (quadPoints->error);

    return HPDF_OK;
}
HPDF_Annotation
HPDF_Annotation_New  (HPDF_MMgr       mmgr,
                      HPDF_Xref       xref,
                      HPDF_AnnotType  type,
                      HPDF_Rect       rect)
{
    HPDF_Annotation annot;
    HPDF_Array array;
    HPDF_STATUS ret = HPDF_OK;
    HPDF_REAL tmp;

    HPDF_PTRACE((" HPDF_Annotation_New\n"));

    annot = HPDF_Dict_New (mmgr);
    if (!annot)
        return NULL;

    if (HPDF_Xref_Add (xref, annot) != HPDF_OK)
        return NULL;

    array = HPDF_Array_New (mmgr);
    if (!array)
        return NULL;

    if (HPDF_Dict_Add (annot, "Rect", array) != HPDF_OK)
        return NULL;

    if (rect.top < rect.bottom) {
        tmp = rect.top;
        rect.top = rect.bottom;
        rect.bottom = tmp;
    }

    ret += HPDF_Array_AddReal (array, rect.left);
    ret += HPDF_Array_AddReal (array, rect.bottom);
    ret += HPDF_Array_AddReal (array, rect.right);
    ret += HPDF_Array_AddReal (array, rect.top);

    ret += HPDF_Dict_AddName (annot, "Type", "Annot");
    ret += HPDF_Dict_AddName (annot, "Subtype",
                    HPDF_ANNOT_TYPE_NAMES[(HPDF_INT)type]);

    if (ret != HPDF_OK)
        return NULL;

    annot->header.obj_class |= HPDF_OSUBCLASS_ANNOTATION;

    return annot;
}
HPDF_MarkupAnnot_SetInteriorRGBColor (HPDF_Annotation  annot, HPDF_RGBColor color)/* IC with RGB entry */
{
    HPDF_Array cArray;
    HPDF_STATUS ret = HPDF_OK;

    HPDF_PTRACE((" HPDF_MarkupAnnot_SetInteriorRGBColor\n"));

    cArray = HPDF_Array_New ( annot->mmgr);
    if (!cArray)
        return HPDF_Error_GetCode ( annot->error);

    ret += HPDF_Dict_Add (annot, "IC", cArray);
    ret += HPDF_Array_AddReal (cArray, color.r);
    ret += HPDF_Array_AddReal (cArray, color.g);
    ret += HPDF_Array_AddReal (cArray, color.b);

    if (ret != HPDF_OK)
        return HPDF_Error_GetCode (annot->error);

    return HPDF_OK;
}
HPDF_Annot_SetRGBColor (HPDF_Annotation annot, HPDF_RGBColor color)
{
    HPDF_Array cArray;
    HPDF_STATUS ret = HPDF_OK;

    HPDF_PTRACE((" HPDF_Annot_SetRGBColor\n"));

    cArray = HPDF_Array_New ( annot->mmgr);
    if (!cArray)
        return HPDF_Error_GetCode ( annot->error);

    ret += HPDF_Dict_Add (annot, "C", cArray);
    ret += HPDF_Array_AddReal (cArray, color.r);
    ret += HPDF_Array_AddReal (cArray, color.g);
    ret += HPDF_Array_AddReal (cArray, color.b);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode (annot->error);

    return HPDF_OK;
}
HPDF_LineAnnot_SetPosition (HPDF_Annotation annot,
                            HPDF_Point startPoint, HPDF_LineAnnotEndingStyle startStyle,
                            HPDF_Point endPoint, HPDF_LineAnnotEndingStyle endStyle)
{
    HPDF_Array lineEndPoints;
    HPDF_Array lineEndStyles;
    HPDF_STATUS ret = HPDF_OK;

    HPDF_PTRACE((" HPDF_LineAnnot_SetPosition\n"));

    lineEndPoints = HPDF_Array_New ( annot->mmgr);
    if ( !lineEndPoints)
        return HPDF_Error_GetCode ( annot->error);

    if ((ret = HPDF_Dict_Add ( annot, "L", lineEndPoints)) != HPDF_OK)
        return ret;

    ret += HPDF_Array_AddReal (lineEndPoints, startPoint.x);
    ret += HPDF_Array_AddReal (lineEndPoints, startPoint.y);
    ret += HPDF_Array_AddReal (lineEndPoints, endPoint.x);
    ret += HPDF_Array_AddReal (lineEndPoints, endPoint.y);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode ( lineEndPoints->error);

    lineEndStyles = HPDF_Array_New ( annot->mmgr);
    if ( !lineEndStyles)
        return HPDF_Error_GetCode ( annot->error);

    if ((ret = HPDF_Dict_Add ( annot, "LE", lineEndStyles)) != HPDF_OK)
        return ret;

    ret += HPDF_Array_AddName (lineEndStyles, HPDF_LINE_ANNOT_ENDING_STYLE_NAMES[(HPDF_INT)startStyle]);
    ret += HPDF_Array_AddName (lineEndStyles, HPDF_LINE_ANNOT_ENDING_STYLE_NAMES[(HPDF_INT)endStyle]);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode ( lineEndStyles->error);

    return HPDF_OK;
}
HPDF_FreeTextAnnot_Set3PointCalloutLine ( HPDF_Annotation annot, HPDF_Point startPoint, HPDF_Point kneePoint, HPDF_Point endPoint) /* Callout line will be in default user space */
{
    HPDF_Array clPoints;
    HPDF_STATUS ret = HPDF_OK;

    HPDF_PTRACE((" HPDF_FreeTextAnnot_Set3PointCalloutLine\n"));

    clPoints = HPDF_Array_New ( annot->mmgr);
    if ( !clPoints)
        return HPDF_Error_GetCode ( annot->error);

    if ((ret = HPDF_Dict_Add ( annot, "CL", clPoints)) != HPDF_OK)
        return ret;

    ret += HPDF_Array_AddReal (clPoints, startPoint.x);
    ret += HPDF_Array_AddReal (clPoints, startPoint.y);
    ret += HPDF_Array_AddReal (clPoints, kneePoint.x);
    ret += HPDF_Array_AddReal (clPoints, kneePoint.y);
    ret += HPDF_Array_AddReal (clPoints, endPoint.x);
    ret += HPDF_Array_AddReal (clPoints, endPoint.y);

    if (ret != HPDF_OK)
       return HPDF_Error_GetCode (clPoints->error);

    return HPDF_OK;
}
HPDF_LinkAnnot_SetBorderStyle  (HPDF_Annotation  annot,
                                HPDF_REAL        width,
                                HPDF_UINT16      dash_on,
                                HPDF_UINT16      dash_off)
{
    HPDF_Array array;
    HPDF_STATUS ret;

    HPDF_PTRACE((" HPDF_LinkAnnot_SetBorderStyle\n"));

    if (!CheckSubType (annot, HPDF_ANNOT_LINK))
        return HPDF_INVALID_ANNOTATION;

    if (width < 0)
        return HPDF_RaiseError (annot->error, HPDF_INVALID_PARAMETER, 0);

    array = HPDF_Array_New (annot->mmgr);
    if (!array)
        return HPDF_CheckError (annot->error);

    if ((ret = HPDF_Dict_Add (annot, "Border", array)) != HPDF_OK)
        return HPDF_CheckError (annot->error);

    ret += HPDF_Array_AddNumber (array, 0);
    ret += HPDF_Array_AddNumber (array, 0);
    ret += HPDF_Array_AddReal (array, width);

    if (ret != HPDF_OK)
        return HPDF_CheckError (annot->error);

    if (dash_on && dash_off) {
        HPDF_Array dash = HPDF_Array_New (annot->mmgr);
        if (!dash)
            return HPDF_CheckError (annot->error);

        if ((ret = HPDF_Array_Add (array, dash)) != HPDF_OK)
            return HPDF_CheckError (annot->error);

        ret += HPDF_Array_AddNumber (dash, dash_on);
        ret += HPDF_Array_AddNumber (dash, dash_off);

        if (ret != HPDF_OK)
           return HPDF_CheckError (annot->error);
    }

    return HPDF_OK;
}
Exemple #11
0
HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetCamera(HPDF_Dict view, HPDF_REAL coox, HPDF_REAL cooy, HPDF_REAL cooz, HPDF_REAL c2cx, HPDF_REAL c2cy, HPDF_REAL c2cz, HPDF_REAL roo, HPDF_REAL roll)
{
	HPDF_REAL viewx, viewy, viewz;
	HPDF_REAL leftx, lefty, leftz;
	HPDF_REAL upx, upy, upz;
	HPDF_REAL transx, transy, transz;

	HPDF_Array  matrix; 
	HPDF_STATUS ret = HPDF_OK;

	HPDF_PTRACE ((" HPDF_3DView_SetCamera\n"));

	if (view == NULL) {
		return HPDF_INVALID_U3D_DATA;
	}

	/* view vector (opposite to c2c) */
	viewx = -c2cx;
	viewy = -c2cy;
	viewz = -c2cz;
	
	/* c2c = (0, -1, 0) by default */
	if (viewx == 0.0 && viewy == 0.0 && viewz == 0.0) {
		viewy = 1.0;
	}
	/* normalize view vector */
	normalize(viewx, viewy, viewz);

	/* rotation matrix */

	/* top and bottom views */
	leftx = -1.0f;
	lefty =  0.0f;
	leftz =  0.0f;

	/* up-vector */
	if (viewz < 0.0) /* top view*/
	{
		upx = 0.0f;
		upy = 1.0f;
		upz = 0.0f;
	}
	else /* bottom view*/
	{
		upx = 0.0f;
		upy =-1.0f;
		upz = 0.0f;
	}
	
	if ( fabs(viewx) + fabs(viewy) != 0.0f) /* other views than top and bottom*/
	{
		/* up-vector = up_world - (up_world dot view) view*/
		upx = -viewz*viewx;
		upy = -viewz*viewy;
		upz = -viewz*viewz + 1.0f;
		/* normalize up-vector*/
		normalize(upx, upy, upz);
		/* left vector = up x view*/
		leftx = viewz*upy - viewy*upz;
		lefty = viewx*upz - viewz*upx;
		leftz = viewy*upx - viewx*upy;
		/* normalize left vector*/
		normalize(leftx, lefty, leftz);
	}
	/* apply camera roll*/
	{
		HPDF_REAL leftxprime, leftyprime, leftzprime;
		HPDF_REAL upxprime, upyprime, upzprime;
		HPDF_REAL sinroll, cosroll;

		sinroll =  sin((roll/180.0f)*M_PI);
		cosroll =  cos((roll/180.0f)*M_PI);
		leftxprime = leftx*cosroll + upx*sinroll;
		leftyprime = lefty*cosroll + upy*sinroll;
		leftzprime = leftz*cosroll + upz*sinroll;
		upxprime = upx*cosroll + leftx*sinroll;
		upyprime = upy*cosroll + lefty*sinroll;
		upzprime = upz*cosroll + leftz*sinroll;
		leftx = leftxprime;
		lefty = leftyprime;
		leftz = leftzprime;
		upx = upxprime;
		upy = upyprime;
		upz = upzprime;
	}
	
	/* translation vector*/
	roo = fabs(roo);
	if (roo == 0.0) {
		roo = 0.000000000000000001;
	}
	transx = coox - roo*viewx;
	transy = cooy - roo*viewy;
	transz = cooz - roo*viewz;

	/* transformation matrix*/
	matrix = HPDF_Array_New (view->mmgr);
	if (!matrix) {
		return HPDF_Error_GetCode (view->error);
	}

	ret = HPDF_Array_AddReal (matrix, leftx);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, lefty);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, leftz);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, upx);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, upy);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, upz);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, viewx);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, viewy);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, viewz);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, transx);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, transy);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Array_AddReal (matrix, transz);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Dict_AddName (view, "MS", "M");
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Dict_Add (view, "C2W", matrix);
	if (ret != HPDF_OK) goto failed;

	ret = HPDF_Dict_AddNumber (view, "CO", roo);

failed:
	if (ret != HPDF_OK) {
		HPDF_Array_Free (matrix);
		return ret;
	}
	return ret;
}
Exemple #12
0
HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetBackgroundColor(HPDF_Dict view, HPDF_REAL r, HPDF_REAL g, HPDF_REAL b)
{
	HPDF_Array  color; 
	HPDF_STATUS ret = HPDF_OK;
	HPDF_Dict background;

	HPDF_PTRACE ((" HPDF_3DView_SetBackgroundColor\n"));

	if (view == NULL || r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1) {
		return HPDF_INVALID_U3D_DATA;
	}

	background = HPDF_Dict_New (view->mmgr);
	if (!background) {
		return HPDF_Error_GetCode (view->error);
	}

	color = HPDF_Array_New (view->mmgr);
	if (!color) {
		HPDF_Dict_Free (background);
		return HPDF_Error_GetCode (view->error);
	}

	ret = HPDF_Array_AddReal (color, r);
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}

	ret = HPDF_Array_AddReal (color, g);
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}

	ret = HPDF_Array_AddReal (color, b);
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}


	ret = HPDF_Dict_AddName (background, "Type", "3DBG");
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}

	ret = HPDF_Dict_Add (background, "C", color);
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}

	ret = HPDF_Dict_Add (view, "BG", background);
	if (ret != HPDF_OK) {
		HPDF_Array_Free (color);
		HPDF_Dict_Free (background);
		return ret;
	}
	return ret;
}
Exemple #13
0
HPDF_Shading_New  (HPDF_Doc         pdf,
                   HPDF_ShadingType type,
                   HPDF_ColorSpace  colorSpace,
                   HPDF_REAL xMin, HPDF_REAL xMax,
                   HPDF_REAL yMin, HPDF_REAL yMax)
{
  HPDF_Shading shading;
  HPDF_Array decodeArray;
  HPDF_STATUS ret = HPDF_OK;
  int i;

  HPDF_PTRACE((" HPDF_Shading_New\n"));

  if (!HPDF_HasDoc(pdf)) {
    return NULL;
  }

  /* Validate shading type: */
  switch (type)
  {
    case HPDF_SHADING_FREE_FORM_TRIANGLE_MESH:
      break;

    default:
      HPDF_SetError (pdf->mmgr->error, HPDF_INVALID_SHADING_TYPE, 0);
      return NULL;
  }

  decodeArray = HPDF_Array_New(pdf->mmgr);
  if (!decodeArray) {
    return NULL;
  }

  /* X-range */
  ret += HPDF_Array_AddReal(decodeArray, xMin);
  ret += HPDF_Array_AddReal(decodeArray, xMax);

  /* Y-range */
  ret += HPDF_Array_AddReal(decodeArray, yMin);
  ret += HPDF_Array_AddReal(decodeArray, yMax);

  const char *colName = NULL;
  switch (colorSpace) {
    case HPDF_CS_DEVICE_RGB:
      colName = COL_RGB;
      for (i = 0; i < 3; ++i) {
        ret += HPDF_Array_AddReal(decodeArray, 0.0);
        ret += HPDF_Array_AddReal(decodeArray, 1.0);
      }
      break;

    default:
      HPDF_SetError(pdf->mmgr->error, HPDF_INVALID_COLOR_SPACE, 0);
      return NULL;
  }

  if (ret != HPDF_OK) {
    return NULL;
  }

  shading = HPDF_DictStream_New(pdf->mmgr, pdf->xref);
  if (!shading) {
    return NULL;
  }

  shading->header.obj_class |= HPDF_OSUBCLASS_SHADING;
  ret += HPDF_Dict_AddNumber(shading, "ShadingType", type);
  ret += HPDF_Dict_AddName(shading, "ColorSpace", colName);

  switch (type)
  {
    case HPDF_SHADING_FREE_FORM_TRIANGLE_MESH:
      ret += HPDF_Dict_AddNumber(shading, "BitsPerCoordinate", 32);
      ret += HPDF_Dict_AddNumber(shading, "BitsPerComponent", 8);
      ret += HPDF_Dict_AddNumber(shading, "BitsPerFlag", 8);
      ret += HPDF_Dict_Add(shading, "Decode", decodeArray);
      break;

    default:
      HPDF_SetError (pdf->mmgr->error, HPDF_INVALID_SHADING_TYPE, 0);
      return NULL;
  }

  if (ret != HPDF_OK) {
    return NULL;
  }

  return shading;
}
HPDF_Annotation_SetBorderStyle  (HPDF_Annotation  annot,
                                 HPDF_BSSubtype   subtype,
                                 HPDF_REAL        width,
                                 HPDF_UINT16      dash_on,
                                 HPDF_UINT16      dash_off,
                                 HPDF_UINT16      dash_phase)
{
    HPDF_Dict bs;
    HPDF_Array dash;
    HPDF_STATUS ret;

    HPDF_PTRACE((" HPDF_Annotation_SetBoderStyle\n"));

    bs = HPDF_Dict_New (annot->mmgr);
    if (!bs)
        return HPDF_Error_GetCode (annot->error);

    if ((ret = HPDF_Dict_Add (annot, "BS", bs)) != HPDF_OK)
        return ret;

    if (subtype == HPDF_BS_DASHED) {
        dash = HPDF_Array_New (annot->mmgr);
        if (!dash)
            return HPDF_Error_GetCode (annot->error);

        if ((ret = HPDF_Dict_Add (bs, "D", dash)) != HPDF_OK)
            return ret;

        ret += HPDF_Dict_AddName (bs, "Type", "Border");
        ret += HPDF_Array_AddReal (dash, dash_on);
        ret += HPDF_Array_AddReal (dash, dash_off);

        if (dash_phase  != 0)
            ret += HPDF_Array_AddReal (dash, dash_off);
    }

    switch (subtype) {
        case HPDF_BS_SOLID:
            ret += HPDF_Dict_AddName (bs, "S", "S");
            break;
        case HPDF_BS_DASHED:
            ret += HPDF_Dict_AddName (bs, "S", "D");
            break;
        case HPDF_BS_BEVELED:
            ret += HPDF_Dict_AddName (bs, "S", "B");
            break;
        case HPDF_BS_INSET:
            ret += HPDF_Dict_AddName (bs, "S", "I");
            break;
        case HPDF_BS_UNDERLINED:
            ret += HPDF_Dict_AddName (bs, "S", "U");
            break;
        default:
            return  HPDF_SetError (annot->error, HPDF_ANNOT_INVALID_BORDER_STYLE, 0);
    }

    if (width != HPDF_BS_DEF_WIDTH)
        ret += HPDF_Dict_AddReal (bs, "W", width);

    if (ret != HPDF_OK)
        return HPDF_Error_GetCode (annot->error);

    return HPDF_OK;
}
HPDF_Font
HPDF_Type3RasterFont_New(HPDF_MMgr        mmgr,
	HPDF_FontDef     fontdef,
	HPDF_Encoder     encoder,
	HPDF_Xref        xref)
{
	HPDF_Dict font;
	HPDF_FontAttr attr;
	HPDF_Type3RasterFontDefAttr fontdef_attr;
	HPDF_BasicEncoderAttr encoder_attr;
	HPDF_STATUS ret = 0;
	HPDF_UINT i;

	HPDF_PTRACE((" HPDF_Type3RasterFont_New\n"));

	/* check whether the fontdef object and the encoder object is valid. */
	if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) {
		HPDF_SetError(mmgr->error, HPDF_INVALID_ENCODER_TYPE, 0);
		return NULL;
	}

	if (fontdef->type != HPDF_FONTDEF_TYPE_TYPE3RASTER) {
		HPDF_SetError(mmgr->error, HPDF_INVALID_FONTDEF_TYPE, 0);
		return NULL;
	}

	font = HPDF_Dict_New(mmgr);
	if (!font)
		return NULL;

	font->header.obj_class |= HPDF_OSUBCLASS_FONT;

	attr = HPDF_GetMem(mmgr, sizeof(HPDF_FontAttr_Rec));
	if (!attr) {
		HPDF_Dict_Free(font);
		return NULL;
	}

	font->header.obj_class |= HPDF_OSUBCLASS_FONT;
	font->write_fn = Type3RasterFont_OnWrite;
	font->free_fn = Type3RasterFont_OnFree;

	HPDF_MemSet(attr, 0, sizeof(HPDF_FontAttr_Rec));

	font->attr = attr;
	attr->type = HPDF_FONT_TYPE3;
	attr->writing_mode = HPDF_WMODE_HORIZONTAL;
	attr->text_width_fn = Type3RasterFont_TextWidth;
	attr->measure_text_fn = Type3RasterFont_MeasureText;
	attr->fontdef = fontdef;
	attr->encoder = encoder;
	attr->xref = xref;

	/* singlebyte-font has a widths-array which is an array of 256 signed
	 * short integer.
	 */
	attr->widths = HPDF_GetMem(mmgr, sizeof(HPDF_INT16) * 256);
	if (!attr->widths) {
		HPDF_Dict_Free(font);
		return NULL;
	}

	encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr;

	HPDF_MemSet(attr->widths, 0, sizeof(HPDF_INT16) * 256);
	for (i = 0 /*encoder_attr->first_char*/; i <= 255 /*encoder_attr->last_char*/; i++) {
		HPDF_UINT16 w = HPDF_Type3RasterFontDef_GetWidth(fontdef, i);
		attr->widths[i] = w;
	}

	fontdef_attr = (HPDF_Type3RasterFontDefAttr)fontdef->attr;

	ret += HPDF_Dict_AddName(font, "Name", fontdef->base_font);
	ret += HPDF_Dict_AddName(font, "Type", "Font");
	ret += HPDF_Dict_AddName(font, "Subtype", "Type3");

	HPDF_REAL scale_x = 72.0f / (HPDF_REAL)fontdef_attr->dpi_x;
	HPDF_REAL scale_y = 72.0f / (HPDF_REAL)fontdef_attr->dpi_y;

	HPDF_TransMatrix font_matrix;
	font_matrix.a = scale_x;
	font_matrix.b = 0;
	font_matrix.c = 0;
	font_matrix.d = scale_y;
	font_matrix.x = 0;
	font_matrix.y = 0;

	HPDF_Array array = HPDF_Array_New(mmgr);
	ret += HPDF_Array_AddReal(array, font_matrix.a);
	ret += HPDF_Array_AddReal(array, font_matrix.b);
	ret += HPDF_Array_AddReal(array, font_matrix.c);
	ret += HPDF_Array_AddReal(array, font_matrix.d);
	ret += HPDF_Array_AddReal(array, font_matrix.x);
	ret += HPDF_Array_AddReal(array, font_matrix.y);
	ret += HPDF_Dict_Add(font, "FontMatrix", array);

	HPDF_Array diff_array = HPDF_Array_New(mmgr);
	ret += HPDF_Array_AddNumber(diff_array, 0);
	for (i = 0; i < 256; ++i) {
		char name[3];
		sprintf(name, "%02X", i);
		ret += HPDF_Array_AddName(diff_array, name);
	}
	HPDF_Dict encoding = HPDF_Dict_New(mmgr);
	ret += HPDF_Dict_Add(encoding, "Differences", diff_array);
	ret += HPDF_Dict_Add(font, "Encoding", encoding);

	HPDF_Dict char_procs = HPDF_Dict_New(mmgr);
	for (i = 0; i < 256; ++i) {
		char name[3];
		sprintf(name, "%02X", i);

		HPDF_Dict char_stream_dict = HPDF_DictStream_New(mmgr, xref);
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].width / scale_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " 0 ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].left / scale_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].bottom / scale_y);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].right / scale_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].top / scale_y);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " d1\012");

		HPDF_Stream_WriteStr(char_stream_dict->stream, "q\012");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].pixels_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " 0 0 ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].pixels_y);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].left / scale_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " ");
		HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].bottom / scale_y);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " cm\012");

		HPDF_Stream_WriteStr(char_stream_dict->stream, "BI\012");
		HPDF_Stream_WriteStr(char_stream_dict->stream, "/IM true\012");
		HPDF_Stream_WriteStr(char_stream_dict->stream, "/W ");
		HPDF_Stream_WriteInt(char_stream_dict->stream, fontdef_attr->chars[i].pixels_x);
		HPDF_Stream_WriteStr(char_stream_dict->stream, " /H ");
		HPDF_Stream_WriteInt(char_stream_dict->stream, fontdef_attr->chars[i].pixels_y);
		HPDF_Stream_WriteStr(char_stream_dict->stream, "\012/BPC 1\012");
		HPDF_Stream_WriteStr(char_stream_dict->stream, "/D [1 0]\012");
		HPDF_Stream_WriteStr(char_stream_dict->stream, "ID\012");

		if (fontdef_attr->chars[i].raster_data != NULL)
			HPDF_Stream_Write(char_stream_dict->stream, fontdef_attr->chars[i].raster_data, fontdef_attr->chars[i].raster_data_size);
		
		HPDF_Stream_WriteStr(char_stream_dict->stream, "\012EI\012");
		HPDF_Stream_WriteStr(char_stream_dict->stream, "Q");

		ret += HPDF_Dict_Add(char_procs, name, char_stream_dict);

		if (fontdef_attr->chars[i].left < fontdef->font_bbox.left)
			fontdef->font_bbox.left = fontdef_attr->chars[i].left;
		if (fontdef_attr->chars[i].bottom < fontdef->font_bbox.bottom)
			fontdef->font_bbox.bottom = fontdef_attr->chars[i].bottom;
		if (fontdef_attr->chars[i].right > fontdef->font_bbox.right)
			fontdef->font_bbox.right = fontdef_attr->chars[i].right;
		if (fontdef_attr->chars[i].top > fontdef->font_bbox.top)
			fontdef->font_bbox.top = fontdef_attr->chars[i].top;
	}

	fontdef->font_bbox.left /= scale_x;
	fontdef->font_bbox.bottom /= scale_y;
	fontdef->font_bbox.right /= scale_x;
	fontdef->font_bbox.top /= scale_y;

	ret += HPDF_Dict_Add(font, "CharProcs", char_procs);

	array = HPDF_Box_Array_New(mmgr, fontdef->font_bbox);
	ret += HPDF_Dict_Add(font, "FontBBox", array);

	if (ret != HPDF_OK) {
		HPDF_Dict_Free(font);
		return NULL;
	}

	if (HPDF_Xref_Add(xref, font) != HPDF_OK)
		return NULL;

	return font;
}