コード例 #1
0
void CFX_PathGenerator::AddPie(FX_FLOAT x,
                               FX_FLOAT y,
                               FX_FLOAT width,
                               FX_FLOAT height,
                               FX_FLOAT start_angle,
                               FX_FLOAT sweep_angle) {
  if (sweep_angle == 0) {
    int old_count = m_pPathData->GetPointCount();
    m_pPathData->AddPointCount(2);
    m_pPathData->SetPoint(old_count, x, y, FXPT_MOVETO);
    m_pPathData->SetPoint(
        old_count + 1, x + FXSYS_Mul(width, FXSYS_cos(start_angle)),
        y + FXSYS_Mul(height, FXSYS_sin(start_angle)), FXPT_LINETO);
    return;
  }
  AddArc(x, y, width, height, start_angle, sweep_angle);
  m_pPathData->AddPointCount(1);
  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y,
                        FXPT_LINETO | FXPT_CLOSEFIGURE);
}
コード例 #2
0
void CPDF_StreamContentParser::Handle_ShowText_Positioning() {
  CPDF_Array* pArray = GetObject(0) ? GetObject(0)->GetArray() : NULL;
  if (!pArray) {
    return;
  }
  int n = pArray->GetCount();
  int nsegs = 0;
  for (int i = 0; i < n; i++) {
    if (pArray->GetElementValue(i)->IsString())
      nsegs++;
  }
  if (nsegs == 0) {
    for (int i = 0; i < n; i++) {
      m_pCurStates->m_TextX -=
          FXSYS_Mul(pArray->GetNumber(i),
                    m_pCurStates->m_TextState.GetFontSize()) /
          1000;
    }
    return;
  }
  CFX_ByteString* pStrs = new CFX_ByteString[nsegs];
  FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs);
  int iSegment = 0;
  FX_FLOAT fInitKerning = 0;
  for (int i = 0; i < n; i++) {
    CPDF_Object* pObj = pArray->GetElementValue(i);
    if (pObj->IsString()) {
      CFX_ByteString str = pObj->GetString();
      if (str.IsEmpty()) {
        continue;
      }
      pStrs[iSegment] = str;
      pKerning[iSegment++] = 0;
    } else {
      FX_FLOAT num = pObj ? pObj->GetNumber() : 0;
      if (iSegment == 0) {
        fInitKerning += num;
      } else {
        pKerning[iSegment - 1] += num;
      }
    }
  }
  AddTextObject(pStrs, fInitKerning, pKerning, iSegment);
  delete[] pStrs;
  FX_Free(pKerning);
}
コード例 #3
0
ファイル: fx_ge_path.cpp プロジェクト: hoanganhx86/pdfium
static void _UpdateLineJoinPoints(CFX_FloatRect& rect,
                                  FX_FLOAT start_x,
                                  FX_FLOAT start_y,
                                  FX_FLOAT middle_x,
                                  FX_FLOAT middle_y,
                                  FX_FLOAT end_x,
                                  FX_FLOAT end_y,
                                  FX_FLOAT half_width,
                                  FX_FLOAT miter_limit) {
  FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0,
           start_dc = 0, end_len = 0, end_dc = 0;
  FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
  FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
  if (bStartVert && bEndVert) {
    int start_dir = middle_y > start_y ? 1 : -1;
    FX_FLOAT point_y = middle_y + half_width * start_dir;
    rect.UpdateRect(middle_x + half_width, point_y);
    rect.UpdateRect(middle_x - half_width, point_y);
    return;
  }
  if (!bStartVert) {
    start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
    start_c = middle_y - FXSYS_Mul(start_k, middle_x);
    start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
    start_dc = (FX_FLOAT)FXSYS_fabs(
        FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
  }
  if (!bEndVert) {
    end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
    end_c = middle_y - FXSYS_Mul(end_k, middle_x);
    end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
    end_dc = (FX_FLOAT)FXSYS_fabs(
        FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
  }
  if (bStartVert) {
    FX_FLOAT outside_x = start_x;
    if (end_x < start_x) {
      outside_x += half_width;
    } else {
      outside_x -= half_width;
    }
    FX_FLOAT outside_y;
    if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
      outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
    } else {
      outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
    }
    rect.UpdateRect(outside_x, outside_y);
    return;
  }
  if (bEndVert) {
    FX_FLOAT outside_x = end_x;
    if (start_x < end_x) {
      outside_x += half_width;
    } else {
      outside_x -= half_width;
    }
    FX_FLOAT outside_y;
    if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
      outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
    } else {
      outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
    }
    rect.UpdateRect(outside_x, outside_y);
    return;
  }
  if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
    int start_dir = middle_x > start_x ? 1 : -1;
    int end_dir = end_x > middle_x ? 1 : -1;
    if (start_dir == end_dir) {
      _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
    } else {
      _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y,
                           half_width);
    }
    return;
  }
  FX_FLOAT start_outside_c = start_c;
  if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
    start_outside_c += start_dc;
  } else {
    start_outside_c -= start_dc;
  }
  FX_FLOAT end_outside_c = end_c;
  if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
    end_outside_c += end_dc;
  } else {
    end_outside_c -= end_dc;
  }
  FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
  FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
  rect.UpdateRect(join_x, join_y);
}
コード例 #4
0
static void DrawAxialShading(CFX_DIBitmap* pBitmap,
                             CFX_Matrix* pObject2Bitmap,
                             CPDF_Dictionary* pDict,
                             CPDF_Function** pFuncs,
                             int nFuncs,
                             CPDF_ColorSpace* pCS,
                             int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Array* pCoords = pDict->GetArray("Coords");
  if (!pCoords) {
    return;
  }
  FX_FLOAT start_x = pCoords->GetNumber(0);
  FX_FLOAT start_y = pCoords->GetNumber(1);
  FX_FLOAT end_x = pCoords->GetNumber(2);
  FX_FLOAT end_y = pCoords->GetNumber(3);
  FX_FLOAT t_min = 0, t_max = 1.0f;
  CPDF_Array* pArray = pDict->GetArray("Domain");
  if (pArray) {
    t_min = pArray->GetNumber(0);
    t_max = pArray->GetNumber(1);
  }
  FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
  pArray = pDict->GetArray("Extend");
  if (pArray) {
    bStartExtend = pArray->GetInteger(0);
    bEndExtend = pArray->GetInteger(1);
  }
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  FX_FLOAT x_span = end_x - start_x;
  FX_FLOAT y_span = end_y - start_y;
  FX_FLOAT axis_len_square =
      FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
  CFX_Matrix matrix;
  matrix.SetReverse(*pObject2Bitmap);
  int total_results = 0;
  for (int j = 0; j < nFuncs; j++) {
    if (pFuncs[j]) {
      total_results += pFuncs[j]->CountOutputs();
    }
  }
  if (pCS->CountComponents() > total_results) {
    total_results = pCS->CountComponents();
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
  FX_FLOAT* pResults = result_array;
  FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
  FX_DWORD rgb_array[SHADING_STEPS];
  for (int i = 0; i < SHADING_STEPS; i++) {
    FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
    int offset = 0;
    for (int j = 0; j < nFuncs; j++) {
      if (pFuncs[j]) {
        int nresults = 0;
        if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
          offset += nresults;
        }
      }
    }
    FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
    pCS->GetRGB(pResults, R, G, B);
    rgb_array[i] =
        FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
                                 FXSYS_round(G * 255), FXSYS_round(B * 255)));
  }
  int pitch = pBitmap->GetPitch();
  for (int row = 0; row < height; row++) {
    FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
    for (int column = 0; column < width; column++) {
      FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
      matrix.Transform(x, y);
      FX_FLOAT scale = FXSYS_Div(
          FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
          axis_len_square);
      int index = (int32_t)(scale * (SHADING_STEPS - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      } else if (index >= SHADING_STEPS) {
        if (!bEndExtend) {
          continue;
        }
        index = SHADING_STEPS - 1;
      }
      dib_buf[column] = rgb_array[index];
    }
  }
}
コード例 #5
0
static void DrawRadialShading(CFX_DIBitmap* pBitmap,
                              CFX_Matrix* pObject2Bitmap,
                              CPDF_Dictionary* pDict,
                              CPDF_Function** pFuncs,
                              int nFuncs,
                              CPDF_ColorSpace* pCS,
                              int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Array* pCoords = pDict->GetArray("Coords");
  if (!pCoords) {
    return;
  }
  FX_FLOAT start_x = pCoords->GetNumber(0);
  FX_FLOAT start_y = pCoords->GetNumber(1);
  FX_FLOAT start_r = pCoords->GetNumber(2);
  FX_FLOAT end_x = pCoords->GetNumber(3);
  FX_FLOAT end_y = pCoords->GetNumber(4);
  FX_FLOAT end_r = pCoords->GetNumber(5);
  CFX_Matrix matrix;
  matrix.SetReverse(*pObject2Bitmap);
  FX_FLOAT t_min = 0, t_max = 1.0f;
  CPDF_Array* pArray = pDict->GetArray("Domain");
  if (pArray) {
    t_min = pArray->GetNumber(0);
    t_max = pArray->GetNumber(1);
  }
  FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
  pArray = pDict->GetArray("Extend");
  if (pArray) {
    bStartExtend = pArray->GetInteger(0);
    bEndExtend = pArray->GetInteger(1);
  }
  int total_results = 0;
  for (int j = 0; j < nFuncs; j++) {
    if (pFuncs[j]) {
      total_results += pFuncs[j]->CountOutputs();
    }
  }
  if (pCS->CountComponents() > total_results) {
    total_results = pCS->CountComponents();
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
  FX_FLOAT* pResults = result_array;
  FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
  FX_DWORD rgb_array[SHADING_STEPS];
  for (int i = 0; i < SHADING_STEPS; i++) {
    FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
    int offset = 0;
    for (int j = 0; j < nFuncs; j++) {
      if (pFuncs[j]) {
        int nresults;
        if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) {
          offset += nresults;
        }
      }
    }
    FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
    pCS->GetRGB(pResults, R, G, B);
    rgb_array[i] =
        FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
                                 FXSYS_round(G * 255), FXSYS_round(B * 255)));
  }
  FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) +
               FXSYS_Mul(start_y - end_y, start_y - end_y) -
               FXSYS_Mul(start_r - end_r, start_r - end_r);
  int width = pBitmap->GetWidth();
  int height = pBitmap->GetHeight();
  int pitch = pBitmap->GetPitch();
  FX_BOOL bDecreasing = FALSE;
  if (start_r > end_r) {
    int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) +
                                  FXSYS_Mul(start_y - end_y, start_y - end_y)));
    if (length < start_r - end_r) {
      bDecreasing = TRUE;
    }
  }
  for (int row = 0; row < height; row++) {
    FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch);
    for (int column = 0; column < width; column++) {
      FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
      matrix.Transform(x, y);
      FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) +
                         FXSYS_Mul(y - start_y, end_y - start_y) +
                         FXSYS_Mul(start_r, end_r - start_r));
      FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) +
                   FXSYS_Mul(y - start_y, y - start_y) -
                   FXSYS_Mul(start_r, start_r);
      FX_FLOAT s;
      if (a == 0) {
        s = FXSYS_Div(-c, b);
      } else {
        FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
        if (b2_4ac < 0) {
          continue;
        }
        FX_FLOAT root = FXSYS_sqrt(b2_4ac);
        FX_FLOAT s1, s2;
        if (a > 0) {
          s1 = FXSYS_Div(-b - root, 2 * a);
          s2 = FXSYS_Div(-b + root, 2 * a);
        } else {
          s2 = FXSYS_Div(-b - root, 2 * a);
          s1 = FXSYS_Div(-b + root, 2 * a);
        }
        if (bDecreasing) {
          if (s1 >= 0 || bStartExtend) {
            s = s1;
          } else {
            s = s2;
          }
        } else {
          if (s2 <= 1.0f || bEndExtend) {
            s = s2;
          } else {
            s = s1;
          }
        }
        if ((start_r + s * (end_r - start_r)) < 0) {
          continue;
        }
      }
      int index = (int32_t)(s * (SHADING_STEPS - 1));
      if (index < 0) {
        if (!bStartExtend) {
          continue;
        }
        index = 0;
      }
      if (index >= SHADING_STEPS) {
        if (!bEndExtend) {
          continue;
        }
        index = SHADING_STEPS - 1;
      }
      dib_buf[column] = rgb_array[index];
    }
  }
}
コード例 #6
0
CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
                               int dest_width, int dest_height, const FX_RECT& clip_rect,
                               const CFX_DIBSource* pSrcBitmap, int flags)
{
    m_State = 0;
    m_DestFormat = dest_format;
    m_DestBpp = dest_format & 0xff;
    m_SrcBpp = pSrcBitmap->GetFormat() & 0xff;
    m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200;
    m_pSrcPalette = pSrcBitmap->GetPalette();
    m_pDestBitmap = pDestBitmap;
    m_DestWidth = dest_width;
    m_DestHeight = dest_height;
    m_pInterBuf = NULL;
    m_pExtraAlphaBuf = NULL;
    m_pDestMaskScanline = NULL;
    m_DestClip = clip_rect;
    FX_DWORD size = clip_rect.Width();
    if (size && m_DestBpp > (int)(INT_MAX / size)) {
        return;
    }
    size *= m_DestBpp;
    if (size > INT_MAX - 31) {
        return;
    }
    size += 31;
    size = size / 32 * 4;
    m_pDestScanline = FX_AllocNL(FX_BYTE, size);
    if (m_pDestScanline == NULL) {
        return;
    }
    if (dest_format == FXDIB_Rgb32) {
        FXSYS_memset8(m_pDestScanline, 255, size);
    }
    m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4;
    m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4;
    m_pInterBuf = NULL;
    m_pSource = pSrcBitmap;
    m_SrcWidth = pSrcBitmap->GetWidth();
    m_SrcHeight = pSrcBitmap->GetHeight();
    m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4;
    if ((flags & FXDIB_NOSMOOTH) == 0) {
        FX_BOOL bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL;
        if (!bInterpol && FXSYS_abs(dest_width) != 0 && FXSYS_abs(dest_height) < m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) {
            flags = FXDIB_INTERPOL;
        }
        m_Flags = flags;
    } else {
        m_Flags = FXDIB_NOSMOOTH;
        if (flags & FXDIB_DOWNSAMPLE) {
            m_Flags |= FXDIB_DOWNSAMPLE;
        }
    }
    double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth));
    double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight));
    double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth);
    double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight);
    double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x);
    double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x);
    double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y);
    double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y);
    if (src_left > src_right) {
        double temp = src_left;
        src_left = src_right;
        src_right = temp;
    }
    if (src_top > src_bottom) {
        double temp = src_top;
        src_top = src_bottom;
        src_bottom = temp;
    }
    m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left);
    m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right);
    m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top);
    m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom);
    FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight);
    m_SrcClip.Intersect(src_rect);
    if (m_SrcBpp == 1) {
        if (m_DestBpp == 8) {
            m_TransMethod = 1;
        } else {
            m_TransMethod = 2;
        }
    } else if (m_SrcBpp == 8) {
        if (m_DestBpp == 8) {
            if (!m_bHasAlpha) {
                m_TransMethod = 3;
            } else {
                m_TransMethod = 4;
            }
        } else {
            if (!m_bHasAlpha) {
                m_TransMethod = 5;
            } else {
                m_TransMethod = 6;
            }
        }
    } else {
        if (!m_bHasAlpha) {
            m_TransMethod = 7;
        } else {
            m_TransMethod = 8;
        }
    }
}
コード例 #7
0
void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX,
                                       FX_FLOAT* pTextAdvanceY,
                                       FX_FLOAT horz_scale,
                                       int level)
{
    FX_FLOAT curpos = 0;
    FX_FLOAT min_x = 10000 * 1.0f;
    FX_FLOAT max_x = -10000 * 1.0f;
    FX_FLOAT min_y = 10000 * 1.0f;
    FX_FLOAT max_y = -10000 * 1.0f;
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize();
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
                            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
            continue;
        }
        if (i) {
            m_pCharPos[i - 1] = curpos;
        }
        FX_RECT char_rect;
        pFont->GetCharBBox(charcode, char_rect, level);
        FX_FLOAT charwidth;
        if (!bVertWriting) {
            if (min_y > char_rect.top) {
                min_y = (FX_FLOAT)char_rect.top;
            }
            if (max_y < char_rect.top) {
                max_y = (FX_FLOAT)char_rect.top;
            }
            if (min_y > char_rect.bottom) {
                min_y = (FX_FLOAT)char_rect.bottom;
            }
            if (max_y < char_rect.bottom) {
                max_y = (FX_FLOAT)char_rect.bottom;
            }
            FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
            FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
            if (min_x > char_left) {
                min_x = char_left;
            }
            if (max_x < char_left) {
                max_x = char_left;
            }
            if (min_x > char_right) {
                min_x = char_right;
            }
            if (max_x < char_right) {
                max_x = char_right;
            }
            charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
        } else {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            short vx;
            short vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            char_rect.left -= vx;
            char_rect.right -= vx;
            char_rect.top -= vy;
            char_rect.bottom -= vy;
            if (min_x > char_rect.left) {
                min_x = (FX_FLOAT)char_rect.left;
            }
            if (max_x < char_rect.left) {
                max_x = (FX_FLOAT)char_rect.left;
            }
            if (min_x > char_rect.right) {
                min_x = (FX_FLOAT)char_rect.right;
            }
            if (max_x < char_rect.right) {
                max_x = (FX_FLOAT)char_rect.right;
            }
            FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
            FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
            if (min_y > char_top) {
                min_y = char_top;
            }
            if (max_y < char_top) {
                max_y = char_top;
            }
            if (min_y > char_bottom) {
                min_y = char_bottom;
            }
            if (max_y < char_bottom) {
                max_y = char_bottom;
            }
            charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
        }
        curpos += charwidth;
        if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) {
            curpos += m_TextState.GetObject()->m_WordSpace;
        }
        curpos += m_TextState.GetObject()->m_CharSpace;
    }
    if (bVertWriting) {
        if (pTextAdvanceX) {
            *pTextAdvanceX = 0;
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = curpos;
        }
        min_x = min_x * fontsize / 1000;
        max_x = max_x * fontsize / 1000;
    } else {
        if (pTextAdvanceX) {
            *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = 0;
        }
        min_y = min_y * fontsize / 1000;
        max_y = max_y * fontsize / 1000;
    }
    CFX_AffineMatrix matrix;
    GetTextMatrix(&matrix);
    m_Left = min_x;
    m_Right = max_x;
    m_Bottom = min_y;
    m_Top = max_y;
    matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
    int textmode = m_TextState.GetObject()->m_TextMode;
    if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
        FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
        m_Left -= half_width;
        m_Right += half_width;
        m_Top += half_width;
        m_Bottom -= half_width;
    }
}
コード例 #8
0
void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs,
                                             FX_FLOAT fInitKerning,
                                             FX_FLOAT* pKerning,
                                             int nsegs) {
  CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont();
  if (!pFont) {
    return;
  }
  if (fInitKerning != 0) {
    if (!pFont->IsVertWriting()) {
      m_pCurStates->m_TextX -=
          FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) /
          1000;
    } else {
      m_pCurStates->m_TextY -=
          FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) /
          1000;
    }
  }
  if (nsegs == 0) {
    return;
  }
  int textmode;
  if (pFont->GetFontType() == PDFFONT_TYPE3) {
    textmode = 0;
  } else {
    textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode;
  }
  CPDF_TextObject* pText = new CPDF_TextObject;
  m_pLastTextObject = pText;
  SetGraphicStates(pText, TRUE, TRUE, TRUE);
  if (textmode && textmode != 3 && textmode != 4 && textmode != 7) {
    FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM;
    pCTM[0] = m_pCurStates->m_CTM.a;
    pCTM[1] = m_pCurStates->m_CTM.c;
    pCTM[2] = m_pCurStates->m_CTM.b;
    pCTM[3] = m_pCurStates->m_CTM.d;
  }
  pText->SetSegments(pStrs, pKerning, nsegs);
  pText->m_PosX = m_pCurStates->m_TextX;
  pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise;
  ConvertTextSpace(pText->m_PosX, pText->m_PosY);
  FX_FLOAT x_advance, y_advance;
  pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale,
                          m_Level);
  m_pCurStates->m_TextX += x_advance;
  m_pCurStates->m_TextY += y_advance;
  if (textmode > 3) {
    CPDF_TextObject* pCopy = new CPDF_TextObject;
    pCopy->Copy(pText);
    m_ClipTextList.Add(pCopy);
  }
  m_pObjectList->m_ObjectList.AddTail(pText);
  if (pKerning && pKerning[nsegs - 1] != 0) {
    if (!pFont->IsVertWriting()) {
      m_pCurStates->m_TextX -=
          FXSYS_Mul(pKerning[nsegs - 1],
                    m_pCurStates->m_TextState.GetFontSize()) /
          1000;
    } else {
      m_pCurStates->m_TextY -=
          FXSYS_Mul(pKerning[nsegs - 1],
                    m_pCurStates->m_TextState.GetFontSize()) /
          1000;
    }
  }
}
コード例 #9
0
void CFX_PathGenerator::AddArc(FX_FLOAT x,
                               FX_FLOAT y,
                               FX_FLOAT width,
                               FX_FLOAT height,
                               FX_FLOAT start_angle,
                               FX_FLOAT sweep_angle) {
#if 0
    FX_FIXFLOAT32 sweep = sweep_angle;
    while (sweep > FIXFLOAT32_PI * 2) {
        sweep -= FIXFLOAT32_PI * 2;
    }
    if (sweep == 0) {
        return;
    }
    m_pPathData->AddPointCount(1);
    m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
                          x + fixmul_8_32_to_8(width, fixcos(start_angle)),
                          y + fixmul_8_32_to_8(height, fixsin(start_angle)), FXPT_MOVETO);
    FX_FIXFLOAT32 angle1 = 0, angle2;
    FX_BOOL bDone = FALSE;
    do {
        angle2 = angle1 + FIXFLOAT32_PI / 2;
        if (angle2 >= sweep) {
            angle2 = sweep;
            bDone = TRUE;
        }
        ArcTo(x, y, width, height, start_angle + angle1, angle2 - angle1);
        angle1 = angle2;
    } while (!bDone);
#else
  if (sweep_angle == 0) {
    return;
  }
  static const FX_FLOAT bezier_arc_angle_epsilon = (FX_FLOAT)(0.01f);
  while (start_angle > FX_PI * 2) {
    start_angle -= FX_PI * 2;
  }
  while (start_angle < 0) {
    start_angle += FX_PI * 2;
  }
  if (sweep_angle >= FX_PI * 2) {
    sweep_angle = FX_PI * 2;
  }
  if (sweep_angle <= -FX_PI * 2) {
    sweep_angle = -FX_PI * 2;
  }
  m_pPathData->AddPointCount(1);
  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
                        x + FXSYS_Mul(width, FXSYS_cos(start_angle)),
                        y + FXSYS_Mul(height, FXSYS_sin(start_angle)),
                        FXPT_MOVETO);
  FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0;
  FX_BOOL done = FALSE;
  do {
    if (sweep_angle < 0) {
      prev_sweep = total_sweep;
      local_sweep = -FX_PI / 2;
      total_sweep -= FX_PI / 2;
      if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = TRUE;
      }
    } else {
      prev_sweep = total_sweep;
      local_sweep = FX_PI / 2;
      total_sweep += FX_PI / 2;
      if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = TRUE;
      }
    }
    ArcTo(x, y, width, height, start_angle, local_sweep);
    start_angle += local_sweep;
  } while (!done);
#endif
}
コード例 #10
0
void CFX_PathGenerator::ArcTo(FX_FLOAT x,
                              FX_FLOAT y,
                              FX_FLOAT width,
                              FX_FLOAT height,
                              FX_FLOAT start_angle,
                              FX_FLOAT sweep_angle) {
  FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2);
  FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2);
  FX_FLOAT tx = FXSYS_Div((1.0f - x0) * 4, 3 * 1.0f);
  FX_FLOAT ty = y0 - FXSYS_Div(FXSYS_Mul(tx, x0), y0);
  FX_FLOAT px[3], py[3];
  px[0] = x0 + tx;
  py[0] = -ty;
  px[1] = x0 + tx;
  py[1] = ty;
  FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2);
  FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2);
  int old_count = m_pPathData->GetPointCount();
  m_pPathData->AddPointCount(3);
  FX_FLOAT bezier_x, bezier_y;
  bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[0], cs) - FXSYS_Mul(py[0], sn));
  bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[0], sn) + FXSYS_Mul(py[0], cs));
  m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[1], cs) - FXSYS_Mul(py[1], sn));
  bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[1], sn) + FXSYS_Mul(py[1], cs));
  m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + FXSYS_Mul(width, FXSYS_cos(start_angle + sweep_angle)),
  bezier_y = y + FXSYS_Mul(height, FXSYS_sin(start_angle + sweep_angle));
  m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO);
}