예제 #1
0
void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
  if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
    CFX_FloatRect rcPlate = GetPlateRect();
    CFX_FloatRect rcContent = GetContentRectInternal();

    if (rcPlate.Height() > rcContent.Height()) {
      fy = rcPlate.top;
    } else {
      if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
        fy = rcContent.bottom + rcPlate.Height();
      } else if (IsFloatBigger(fy, rcContent.top)) {
        fy = rcContent.top;
      }
    }

    m_ptScrollPos.y = fy;
    InvalidateItem(-1);

    if (m_pNotify) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = true;
        m_pNotify->IOnSetScrollPosY(fy);
        m_bNotifyFlag = false;
      }
    }
  }
}
예제 #2
0
void CFDE_Path::GetBBox(CFX_RectF& bbox,
                        FX_FLOAT fLineWidth,
                        FX_FLOAT fMiterLimit) const {
  CFX_FloatRect rect = m_Path.GetBoundingBox(fLineWidth, fMiterLimit);
  bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
  bbox.Normalize();
}
예제 #3
0
CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot,
                     CFX_FloatRect rcStream,
                     const CFX_Matrix& matrix) {
  if (rcStream.IsEmpty())
    return CFX_Matrix();

  matrix.TransformRect(rcStream);
  rcStream.Normalize();

  FX_FLOAT a = rcAnnot.Width() / rcStream.Width();
  FX_FLOAT d = rcAnnot.Height() / rcStream.Height();

  FX_FLOAT e = rcAnnot.left - rcStream.left * a;
  FX_FLOAT f = rcAnnot.bottom - rcStream.bottom * d;
  return CFX_Matrix(a, 0, 0, d, e, f);
}
예제 #4
0
bool CPDF_TextPage::IsSameTextObject(CPDF_TextObject* pTextObj1,
                                     CPDF_TextObject* pTextObj2) {
  if (!pTextObj1 || !pTextObj2)
    return false;

  CFX_FloatRect rcPreObj = pTextObj2->GetRect();
  const CFX_FloatRect& rcCurObj = pTextObj1->GetRect();
  if (rcPreObj.IsEmpty() && rcCurObj.IsEmpty()) {
    float dbXdif = fabs(rcPreObj.left - rcCurObj.left);
    size_t nCount = m_CharList.size();
    if (nCount >= 2) {
      PAGECHAR_INFO perCharTemp = m_CharList[nCount - 2];
      float dbSpace = perCharTemp.m_CharBox.Width();
      if (dbXdif > dbSpace)
        return false;
    }
  }
  if (!rcPreObj.IsEmpty() || !rcCurObj.IsEmpty()) {
    rcPreObj.Intersect(rcCurObj);
    if (rcPreObj.IsEmpty())
      return false;
    if (fabs(rcPreObj.Width() - rcCurObj.Width()) > rcCurObj.Width() / 2) {
      return false;
    }
    if (pTextObj2->GetFontSize() != pTextObj1->GetFontSize())
      return false;
  }

  size_t nPreCount = pTextObj2->CountItems();
  if (nPreCount != pTextObj1->CountItems())
    return false;

  // If both objects have no items, consider them same.
  if (nPreCount == 0)
    return true;

  CPDF_TextObjectItem itemPer;
  CPDF_TextObjectItem itemCur;
  for (size_t i = 0; i < nPreCount; ++i) {
    pTextObj2->GetItemInfo(i, &itemPer);
    pTextObj1->GetItemInfo(i, &itemCur);
    if (itemCur.m_CharCode != itemPer.m_CharCode)
      return false;
  }

  CFX_PointF diff = pTextObj1->GetPos() - pTextObj2->GetPos();
  float font_size = pTextObj2->GetFontSize();
  float char_size = GetCharWidth(itemPer.m_CharCode, pTextObj2->GetFont());
  float max_pre_size =
      std::max(std::max(rcPreObj.Height(), rcPreObj.Width()), font_size);
  return fabs(diff.x) <= 0.9 * char_size * font_size / 1000 &&
         fabs(diff.y) <= max_pre_size / 8;
}
예제 #5
0
void CFX_ListCtrl::SetScrollInfo() {
  if (m_pNotify) {
    CFX_FloatRect rcPlate = GetPlateRect();
    CFX_FloatRect rcContent = GetContentRectInternal();

    if (!m_bNotifyFlag) {
      m_bNotifyFlag = true;
      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                                   rcContent.bottom, rcContent.top,
                                   GetFirstHeight(), rcPlate.Height());
      m_bNotifyFlag = false;
    }
  }
}
예제 #6
0
FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
                                             const CFX_FloatRect& rcPlate,
                                             int32_t nCharArray) {
  if (pFont && !pFont->IsStandardFont()) {
    FX_RECT rcBBox;
    pFont->GetFontBBox(rcBBox);

    CFX_FloatRect rcCell = rcPlate;
    FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
    FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();

    return xdiv < ydiv ? xdiv : ydiv;
  }

  return 0.0f;
}
예제 #7
0
void CFX_ListCtrl::ScrollToListItem(int32_t nItemIndex) {
  if (!IsValid(nItemIndex))
    return;

  CFX_FloatRect rcPlate = GetPlateRect();
  CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
  CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);

  if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
    if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
      SetScrollPosY(rcItem.bottom + rcPlate.Height());
    }
  } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
    if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
      SetScrollPosY(rcItem.top);
    }
  }
}
예제 #8
0
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPage_TransFormWithClip(FPDF_PAGE page,
                           const FS_MATRIX* matrix,
                           const FS_RECTF* clipRect) {
  if (!matrix && !clipRect)
    return false;

  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return false;

  std::ostringstream textBuf;
  textBuf << "q ";

  if (clipRect) {
    CFX_FloatRect rect = CFXFloatRectFromFSRECTF(*clipRect);
    rect.Normalize();

    textBuf << ByteString::Format("%f %f %f %f re W* n ", rect.left,
                                  rect.bottom, rect.Width(), rect.Height());
  }
  if (matrix) {
    textBuf << ByteString::Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,
                                  matrix->c, matrix->d, matrix->e, matrix->f);
  }

  CPDF_Dictionary* pPageDict = pPage->GetDict();
  CPDF_Object* pContentObj = GetPageContent(pPageDict);
  if (!pContentObj)
    return false;

  CPDF_Document* pDoc = pPage->GetDocument();
  if (!pDoc)
    return false;

  CPDF_Stream* pStream =
      pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
  pStream->SetDataFromStringstream(&textBuf);

  CPDF_Stream* pEndStream =
      pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
  pEndStream->SetData(ByteStringView(" Q").span());

  if (CPDF_Array* pContentArray = ToArray(pContentObj)) {
    pContentArray->InsertAt(0, pStream->MakeReference(pDoc));
    pContentArray->Add(pEndStream->MakeReference(pDoc));
  } else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
    pContentArray = pDoc->NewIndirect<CPDF_Array>();
    pContentArray->Add(pStream->MakeReference(pDoc));
    pContentArray->Add(pContentObj->MakeReference(pDoc));
    pContentArray->Add(pEndStream->MakeReference(pDoc));
    pPageDict->SetFor(pdfium::page_object::kContents,
                      pContentArray->MakeReference(pDoc));
  }

  // Need to transform the patterns as well.
  CPDF_Dictionary* pRes =
      pPageDict->GetDictFor(pdfium::page_object::kResources);
  if (!pRes)
    return true;

  CPDF_Dictionary* pPatternDict = pRes->GetDictFor("Pattern");
  if (!pPatternDict)
    return true;

  CPDF_DictionaryLocker locker(pPatternDict);
  for (const auto& it : locker) {
    CPDF_Object* pObj = it.second.get();
    if (pObj->IsReference())
      pObj = pObj->GetDirect();

    CPDF_Dictionary* pDict = nullptr;
    if (pObj->IsDictionary())
      pDict = pObj->AsDictionary();
    else if (CPDF_Stream* pObjStream = pObj->AsStream())
      pDict = pObjStream->GetDict();
    else
      continue;

    if (matrix) {
      CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix);
      pDict->SetMatrixFor("Matrix", pDict->GetMatrixFor("Matrix") * m);
    }
  }

  return true;
}
예제 #9
0
void CPDF_ProgressiveReflowPageRender::Display(IFX_Pause* pPause)
{
    if (NULL == m_pReflowPage) {
        m_Status = Done;
        return;
    }
    FX_RECT clipBox = m_pFXDevice->GetClipBox();
    int size = m_pReflowPage->m_pReflowed->GetSize();
    if (size < 1 || NULL == m_pDisplayMatrix) {
        m_Status = Done;
        return;
    }
    for(int i = m_CurrNum; i < size; i++) {
        CRF_Data* pData = (*m_pReflowPage->m_pReflowed)[i];
        if(!pData) {
            continue;
        }
        CFX_FloatRect rect (pData->m_PosX, pData->m_PosY + pData->m_Height, pData->m_PosX + pData->m_Width, pData->m_PosY);
        m_pDisplayMatrix->TransformRect(rect);
        if(rect.left > clipBox.right || rect.right < clipBox.left || rect.bottom > clipBox.bottom || rect.top < clipBox.top) {
            continue;
        }
        if(pData->GetType() == CRF_Data::Text) {
            CRF_CharData* pCharData = (CRF_CharData*)pData;
            CPDF_Font* pPDFFont = pCharData->m_pCharState->m_pFont;
            if(pPDFFont->GetFontType() == PDFFONT_TYPE3) {
                continue;
            }
            FX_FLOAT x = pData->m_PosX, y = pData->m_PosY - pCharData->m_pCharState->m_fDescent;
            FXTEXT_CHARPOS charpos ;
            charpos.m_GlyphIndex = pPDFFont->GlyphFromCharCode(pCharData->m_CharCode);
            charpos.m_FontCharWidth = pPDFFont->m_Font.GetGlyphWidth(charpos.m_GlyphIndex);
            charpos.m_OriginX       = x;
            charpos.m_OriginY       = y;
            FX_FLOAT charW = pData->m_Width * 1000 / pData->m_Height;
            if(charW != charpos.m_FontCharWidth) {
                charpos.m_bGlyphAdjust  = TRUE;
                charpos.m_AdjustMatrix[0] = charW / charpos.m_FontCharWidth;
                charpos.m_AdjustMatrix[1] = 0;
                charpos.m_AdjustMatrix[2] = 0;
                charpos.m_AdjustMatrix[3] = 1;
            } else {
                charpos.m_bGlyphAdjust  = FALSE;
            }
            FX_BOOL bRet = FALSE;
            if(m_DisplayColor == -1)
                bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font),
                                                   NULL, pCharData->m_pCharState->m_fFontSize,
                                                   m_pDisplayMatrix, pCharData->m_pCharState->m_Color + 0xff000000, FXTEXT_CLEARTYPE);
            else
                bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font),
                                                   NULL, pCharData->m_pCharState->m_fFontSize, m_pDisplayMatrix, m_DisplayColor, FXTEXT_CLEARTYPE);
        } else if(pData->GetType() == CRF_Data::Image) {
            CRF_ImageData* pImageData = (CRF_ImageData*)pData;
            if(!pImageData->m_pBitmap) {
                continue;
            }
            int left = 0, top = 0;
            CFX_DIBitmap* pDiBmp = NULL;
            CFX_DIBSource* pDispSource = pImageData->m_pBitmap;
            if(pImageData->m_Matrix.d < 0) {
                CFX_AffineMatrix matrix(pImageData->m_Matrix.a, 0, 0, -pImageData->m_Matrix.d, 0, 0);
                int left, top;
                pDiBmp = pImageData->m_pBitmap->TransformTo(&matrix, left, top);
                pDispSource = pDiBmp;
            }
            if (NULL == pDispSource) {
                continue;
            }
            if (pDispSource->GetFormat() == FXDIB_1bppMask || pDispSource->GetFormat() == FXDIB_8bppMask) {
                m_pFXDevice->StretchBitMask(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5), 0xff000000);
            } else {
                m_pFXDevice->StretchDIBits(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5));
            }
            if(m_pFXDevice->GetBitmap() && m_pFXDevice->GetBitmap()->GetFormat() == FXDIB_8bppRgb &&
                    m_pFXDevice->GetBitmap()->GetPalette() == NULL) {
                int nPalette = 0;
                switch(m_DitherBits) {
                    case 0:
                        nPalette = 0;
                        break;
                    case 1:
                        nPalette = 2;
                        break;
                    case 2:
                        nPalette = 4;
                        break;
                    case 3:
                        nPalette = 8;
                        break;
                    case 4:
                        nPalette = 16;
                        break;
                    case 5:
                        nPalette = 32;
                        break;
                    case 6:
                        nPalette = 64;
                        break;
                    case 7:
                        nPalette = 128;
                        break;
                    default:
                        nPalette = 256;
                        break;
                }
                if(nPalette >= 2) {
                    FX_ARGB * palette = FX_Alloc(FX_ARGB, nPalette);
                    nPalette --;
                    palette[0] = 0;
                    palette[nPalette] = 255;
                    FX_FLOAT Dither = (FX_FLOAT)255 / (nPalette);
                    for(int i = 1; i < nPalette; i++) {
                        palette[i] = (FX_ARGB)(Dither * i + 0.5);
                    }
                    FX_RECT tmpRect = rect.GetOutterRect();
                    m_pFXDevice->GetBitmap()->DitherFS(palette, nPalette + 1, &tmpRect);
                    FX_Free (palette);
                }
            }
            if(pDiBmp) {
                delete pDiBmp;
            }
        } else if(pData->GetType() == CRF_Data::Path) {
        }
        if(!(i % 10)) {
            if(pPause && pPause->NeedToPauseNow()) {
                i++;
                m_CurrNum = i;
                m_Status = ToBeContinued;
                return;
            }
        }
    }
    m_CurrNum = size;
    m_Status = Done;
}
예제 #10
0
void CFDE_Path::GetBBox(CFX_RectF& bbox) const {
  CFX_FloatRect rect = m_Path.GetBoundingBox();
  bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
  bbox.Normalize();
}
예제 #11
0
CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject(
    const CPDF_TextObject* pObj,
    const CFX_Matrix& formMatrix) {
  FindPreviousTextObject();
  TextOrientation WritingMode = GetTextObjectWritingMode(pObj);
  if (WritingMode == TextOrientation::Unknown)
    WritingMode = GetTextObjectWritingMode(m_pPreTextObj.Get());

  size_t nItem = m_pPreTextObj->CountItems();
  if (nItem == 0)
    return GenerateCharacter::None;

  CPDF_TextObjectItem PrevItem;
  m_pPreTextObj->GetItemInfo(nItem - 1, &PrevItem);

  CPDF_TextObjectItem item;
  pObj->GetItemInfo(0, &item);

  const CFX_FloatRect& this_rect = pObj->GetRect();
  const CFX_FloatRect& prev_rect = m_pPreTextObj->GetRect();

  WideString wstrItem = pObj->GetFont()->UnicodeFromCharCode(item.m_CharCode);
  if (wstrItem.IsEmpty())
    wstrItem += static_cast<wchar_t>(item.m_CharCode);
  wchar_t curChar = wstrItem[0];
  if (WritingMode == TextOrientation::Horizontal) {
    if (EndHorizontalLine(this_rect, prev_rect)) {
      return IsHyphen(curChar) ? GenerateCharacter::Hyphen
                               : GenerateCharacter::LineBreak;
    }
  } else if (WritingMode == TextOrientation::Vertical) {
    if (EndVerticalLine(this_rect, prev_rect, m_CurlineRect,
                        pObj->GetFontSize(), m_pPreTextObj->GetFontSize())) {
      return IsHyphen(curChar) ? GenerateCharacter::Hyphen
                               : GenerateCharacter::LineBreak;
    }
  }

  float last_pos = PrevItem.m_Origin.x;
  uint32_t nLastWidth =
      GetCharWidth(PrevItem.m_CharCode, m_pPreTextObj->GetFont());
  float last_width = nLastWidth * m_pPreTextObj->GetFontSize() / 1000;
  last_width = fabs(last_width);
  uint32_t nThisWidth = GetCharWidth(item.m_CharCode, pObj->GetFont());
  float this_width = fabs(nThisWidth * pObj->GetFontSize() / 1000);
  float threshold = std::max(last_width, this_width) / 4;

  CFX_Matrix prev_matrix = m_pPreTextObj->GetTextMatrix() * m_perMatrix;
  CFX_Matrix prev_reverse = prev_matrix.GetInverse();

  CFX_PointF pos = prev_reverse.Transform(formMatrix.Transform(pObj->GetPos()));
  if (last_width < this_width)
    threshold = prev_reverse.TransformDistance(threshold);

  bool bNewline = false;
  if (WritingMode == TextOrientation::Horizontal) {
    CFX_FloatRect rect = m_pPreTextObj->GetRect();
    float rect_height = rect.Height();
    rect.Normalize();
    if ((rect.IsEmpty() && rect_height > 5) ||
        ((pos.y > threshold * 2 || pos.y < threshold * -3) &&
         (fabs(pos.y) >= 1 || fabs(pos.y) > fabs(pos.x)))) {
      bNewline = true;
      if (nItem > 1) {
        CPDF_TextObjectItem tempItem;
        m_pPreTextObj->GetItemInfo(0, &tempItem);
        CFX_Matrix m = m_pPreTextObj->GetTextMatrix();
        if (PrevItem.m_Origin.x > tempItem.m_Origin.x &&
            m_DisplayMatrix.a > 0.9 && m_DisplayMatrix.b < 0.1 &&
            m_DisplayMatrix.c < 0.1 && m_DisplayMatrix.d < -0.9 && m.b < 0.1 &&
            m.c < 0.1) {
          CFX_FloatRect re(0, m_pPreTextObj->GetRect().bottom, 1000,
                           m_pPreTextObj->GetRect().top);
          if (re.Contains(pObj->GetPos())) {
            bNewline = false;
          } else {
            if (CFX_FloatRect(0, pObj->GetRect().bottom, 1000,
                              pObj->GetRect().top)
                    .Contains(m_pPreTextObj->GetPos())) {
              bNewline = false;
            }
          }
        }
      }
    }
  }
  if (bNewline) {
    return IsHyphen(curChar) ? GenerateCharacter::Hyphen
                             : GenerateCharacter::LineBreak;
  }

  if (pObj->CountChars() == 1 && IsHyphenCode(curChar) && IsHyphen(curChar))
    return GenerateCharacter::Hyphen;

  if (curChar == L' ')
    return GenerateCharacter::None;

  WideString PrevStr =
      m_pPreTextObj->GetFont()->UnicodeFromCharCode(PrevItem.m_CharCode);
  wchar_t preChar = PrevStr.Last();
  if (preChar == L' ')
    return GenerateCharacter::None;

  CFX_Matrix matrix = pObj->GetTextMatrix() * formMatrix;
  float threshold2 = static_cast<float>(std::max(nLastWidth, nThisWidth));
  threshold2 = NormalizeThreshold(threshold2, 400, 700, 800);
  if (nLastWidth >= nThisWidth) {
    threshold2 *= fabs(m_pPreTextObj->GetFontSize());
  } else {
    threshold2 *= fabs(pObj->GetFontSize());
    threshold2 = matrix.TransformDistance(threshold2);
    threshold2 = prev_reverse.TransformDistance(threshold2);
  }
  threshold2 /= 1000;
  if ((threshold2 < 1.4881 && threshold2 > 1.4879) ||
      (threshold2 < 1.39001 && threshold2 > 1.38999)) {
    threshold2 *= 1.5;
  }
  return GenerateSpace(pos, last_pos, this_width, last_width, threshold2)
             ? GenerateCharacter::Space
             : GenerateCharacter::None;
}