FX_BOOL CFX_ImageTransformer::Start() { CFX_FloatRect unit_rect = m_pMatrix->GetUnitRect(); FX_RECT result_rect = unit_rect.GetClosestRect(); FX_RECT result_clip = result_rect; if (m_pClip) result_clip.Intersect(*m_pClip); if (result_clip.IsEmpty()) return FALSE; m_result = result_clip; if (FXSYS_fabs(m_pMatrix->a) < FXSYS_fabs(m_pMatrix->b) / 20 && FXSYS_fabs(m_pMatrix->d) < FXSYS_fabs(m_pMatrix->c) / 20 && FXSYS_fabs(m_pMatrix->a) < 0.5f && FXSYS_fabs(m_pMatrix->d) < 0.5f) { int dest_width = result_rect.Width(); int dest_height = result_rect.Height(); result_clip.Offset(-result_rect.left, -result_rect.top); result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height, m_pMatrix->c > 0, m_pMatrix->b < 0); m_Stretcher = WrapUnique(new CFX_ImageStretcher( &m_Storer, m_pSrc, dest_height, dest_width, result_clip, m_Flags)); m_Stretcher->Start(); m_Status = 1; return TRUE; } if (FXSYS_fabs(m_pMatrix->b) < FIX16_005 && FXSYS_fabs(m_pMatrix->c) < FIX16_005) { int dest_width = m_pMatrix->a > 0 ? (int)FXSYS_ceil(m_pMatrix->a) : (int)FXSYS_floor(m_pMatrix->a); int dest_height = m_pMatrix->d > 0 ? (int)-FXSYS_ceil(m_pMatrix->d) : (int)-FXSYS_floor(m_pMatrix->d); result_clip.Offset(-result_rect.left, -result_rect.top); m_Stretcher = WrapUnique(new CFX_ImageStretcher( &m_Storer, m_pSrc, dest_width, dest_height, result_clip, m_Flags)); m_Stretcher->Start(); m_Status = 2; return TRUE; } int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->a, m_pMatrix->b)); int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->c, m_pMatrix->d)); CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height)); stretch2dest.Concat( m_pMatrix->a / stretch_width, m_pMatrix->b / stretch_width, m_pMatrix->c / stretch_height, m_pMatrix->d / stretch_height, m_pMatrix->e, m_pMatrix->f); m_dest2stretch.SetReverse(stretch2dest); CFX_FloatRect clip_rect_f(result_clip); clip_rect_f.Transform(&m_dest2stretch); m_StretchClip = clip_rect_f.GetOuterRect(); m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); m_Stretcher = WrapUnique(new CFX_ImageStretcher(&m_Storer, m_pSrc, stretch_width, stretch_height, m_StretchClip, m_Flags)); m_Stretcher->Start(); m_Status = 3; return TRUE; }

FX_RECT CFX_FloatRect::GetInnerRect() const { CFX_FloatRect rect1 = *this; FX_RECT rect; rect.left = (int)FXSYS_ceil(rect1.left); rect.right = (int)FXSYS_floor(rect1.right); rect.top = (int)FXSYS_ceil(rect1.bottom); rect.bottom = (int)FXSYS_floor(rect1.top); rect.Normalize(); return rect; }

FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { CGRect r = CGContextGetClipBoundingBox(_context); r = CGRectApplyAffineTransform(r, _user2FoxitDevice); rect->left = FXSYS_floor(r.origin.x); rect->top = FXSYS_floor(r.origin.y); rect->right = FXSYS_ceil(r.origin.x + r.size.width); rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); return TRUE; }

static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) { int length = (int)FXSYS_ceil(f2 - f1); int i1_1 = (int)FXSYS_floor(f1); int i1_2 = (int)FXSYS_ceil(f1); FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); i1 = (error1 > error2) ? i1_2 : i1_1; i2 = i1 + length; }

FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix, int flags, const FX_RECT* pDestClip) { m_pMatrix = (CFX_AffineMatrix*)pDestMatrix; CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); FX_RECT result_rect = unit_rect.GetClosestRect(); FX_RECT result_clip = result_rect; if (pDestClip) { result_clip.Intersect(*pDestClip); } if (result_clip.IsEmpty()) { return FALSE; } m_ResultLeft = result_clip.left; m_ResultTop = result_clip.top; m_ResultWidth = result_clip.Width(); m_ResultHeight = result_clip.Height(); m_Flags = flags; if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 && FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 && FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) { int dest_width = result_rect.Width(); int dest_height = result_rect.Height(); result_clip.Offset(-result_rect.left, -result_rect.top); result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, pDestMatrix->c > 0, pDestMatrix->b < 0); m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, flags); m_Status = 1; return TRUE; } if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && FXSYS_fabs(pDestMatrix->c) < FIX16_005) { int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) : (int)FXSYS_floor(pDestMatrix->a); int dest_height = pDestMatrix->d > 0 ? (int) - FXSYS_ceil(pDestMatrix->d) : (int) - FXSYS_floor(pDestMatrix->d); result_clip.Offset(-result_rect.left, -result_rect.top); m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, flags); m_Status = 2; return TRUE; } int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b)); int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d)); CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height)); stretch2dest.Concat(pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width, pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, pDestMatrix->e, pDestMatrix->f); m_dest2stretch.SetReverse(stretch2dest); CFX_FloatRect clip_rect_f(result_clip); clip_rect_f.Transform(&m_dest2stretch); m_StretchClip = clip_rect_f.GetOutterRect(); m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags); m_Status = 3; return TRUE; }

double JS_MakeDay(int nYear, int nMonth, int nDate) { if (!_isfinite(nYear) || !_isfinite(nMonth) ||!_isfinite(nDate)) return GetNan(); double y = _toInteger(nYear); double m = _toInteger(nMonth); double dt = _toInteger(nDate); double ym = y + FXSYS_floor((double)m/12); double mn = _Mod(m ,12); double t = _TimeFromYearMonth((int)ym,(int)mn); if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||_DateFromTime(t) != 1) return GetNan(); return _Day(t)+dt-1; }

void CFWL_CheckBoxImp::Layout() { int32_t width = int32_t(m_pProperties->m_rtWidget.width + 0.5f); int32_t height = int32_t(m_pProperties->m_rtWidget.height + 0.5f); m_pProperties->m_rtWidget.width = (FX_FLOAT)width; m_pProperties->m_rtWidget.height = (FX_FLOAT)height; GetClientRect(m_rtClient); FX_FLOAT fBoxTop = m_rtClient.top; FX_FLOAT fBoxLeft = m_rtClient.left; FX_FLOAT fTextLeft = 0.0, fTextRight = 0.0; FX_FLOAT fClientRight = m_rtClient.right(); FX_FLOAT fClientBottom = m_rtClient.bottom(); if (!m_pProperties->m_pDataProvider) return; IFWL_CheckBoxDP* pData = static_cast<IFWL_CheckBoxDP*>(m_pProperties->m_pDataProvider); FX_FLOAT fCheckBox = pData->GetBoxSize(m_pInterface); switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) { case FWL_STYLEEXT_CKB_Top: { fBoxTop = m_rtClient.top; break; } case FWL_STYLEEXT_CKB_Bottom: { fBoxTop = fClientBottom - fCheckBox; break; } case FWL_STYLEEXT_CKB_VCenter: default: { fBoxTop = m_rtClient.top + (m_rtClient.height - fCheckBox) / 2; fBoxTop = FXSYS_floor(fBoxTop); } } if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_LeftText) { fBoxLeft = fClientRight - fCheckBox; fTextLeft = m_rtClient.left; fTextRight = fBoxLeft; } else { fTextLeft = fBoxLeft + fCheckBox; fTextRight = fClientRight; } m_rtBox.Set(fBoxLeft, fBoxTop, fCheckBox, fCheckBox); m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft, m_rtClient.height); m_rtCaption.Inflate(-FWL_CKB_CaptionMargin, -FWL_CKB_CaptionMargin); CFX_RectF rtFocus; rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, m_rtCaption.height); CFX_WideString wsCaption; m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption); if (wsCaption.IsEmpty()) { m_rtFocus.Set(0, 0, 0, 0); } else { CalcTextRect(wsCaption, m_pProperties->m_pThemeProvider, m_dwTTOStyles, m_iTTOAlign, rtFocus); if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) == 0) { FX_FLOAT fWidth = std::max(m_rtCaption.width, rtFocus.width); FX_FLOAT fHeight = std::min(m_rtCaption.height, rtFocus.height); FX_FLOAT fLeft = m_rtCaption.left; FX_FLOAT fTop = m_rtCaption.top; if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == FWL_STYLEEXT_CKB_Center) { fLeft = m_rtCaption.left + (m_rtCaption.width - fWidth) / 2; } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == FWL_STYLEEXT_CKB_Right) { fLeft = m_rtCaption.right() - fWidth; } if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == FWL_STYLEEXT_CKB_VCenter) { fTop = m_rtCaption.top + (m_rtCaption.height - fHeight) / 2; } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == FWL_STYLEEXT_CKB_Bottom) { fTop = m_rtCaption.bottom() - fHeight; } m_rtFocus.Set(fLeft, fTop, fWidth, fHeight); } else { m_rtFocus.Set(rtFocus.left, rtFocus.top, rtFocus.width, rtFocus.height); } m_rtFocus.Inflate(1, 1); } }

void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_Matrix* pObj2Device, FX_BOOL bStroke) { if (!pPattern->Load()) { return; } m_pDevice->SaveState(); if (pPageObj->m_Type == PDFPAGE_PATH) { if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { m_pDevice->RestoreState(); return; } } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { FX_RECT rect = pPageObj->GetBBox(pObj2Device); m_pDevice->SetClip_Rect(&rect); } else { return; } FX_RECT clip_box = m_pDevice->GetClipBox(); if (clip_box.IsEmpty()) { m_pDevice->RestoreState(); return; } CFX_Matrix dCTM = m_pDevice->GetCTM(); FX_FLOAT sa = FXSYS_fabs(dCTM.a); FX_FLOAT sd = FXSYS_fabs(dCTM.d); clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa); clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd); CFX_Matrix mtPattern2Device = pPattern->m_Pattern2Form; mtPattern2Device.Concat(*pObj2Device); GetScaledMatrix(mtPattern2Device); FX_BOOL bAligned = FALSE; if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 && pPattern->m_BBox.right == pPattern->m_XStep && pPattern->m_BBox.top == pPattern->m_YStep && (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) { bAligned = TRUE; } CFX_FloatRect cell_bbox = pPattern->m_BBox; mtPattern2Device.TransformRect(cell_bbox); int width = (int)FXSYS_ceil(cell_bbox.Width()); int height = (int)FXSYS_ceil(cell_bbox.Height()); if (width == 0) { width = 1; } if (height == 0) { height = 1; } int min_col, max_col, min_row, max_row; CFX_Matrix mtDevice2Pattern; mtDevice2Pattern.SetReverse(mtPattern2Device); CFX_FloatRect clip_box_p(clip_box); clip_box_p.Transform(&mtDevice2Pattern); min_col = (int)FXSYS_ceil( FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep)); max_col = (int)FXSYS_floor( FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep)); min_row = (int)FXSYS_ceil( FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep)); max_row = (int)FXSYS_floor( FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep)); if (width > clip_box.Width() || height > clip_box.Height() || width * height > clip_box.Width() * clip_box.Height()) { CPDF_GraphicStates* pStates = NULL; if (!pPattern->m_bColored) { pStates = CloneObjStates(pPageObj, bStroke); } CPDF_Dictionary* pFormResource = NULL; if (pPattern->m_pForm->m_pFormDict) { pFormResource = pPattern->m_pForm->m_pFormDict->GetDict("Resources"); } for (int col = min_col; col <= max_col; col++) for (int row = min_row; row <= max_row; row++) { FX_FLOAT orig_x, orig_y; orig_x = col * pPattern->m_XStep; orig_y = row * pPattern->m_YStep; mtPattern2Device.Transform(orig_x, orig_y); CFX_Matrix matrix = *pObj2Device; matrix.Translate(orig_x - mtPattern2Device.e, orig_y - mtPattern2Device.f); m_pDevice->SaveState(); CPDF_RenderStatus status; status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &m_Options, pPattern->m_pForm->m_Transparency, m_bDropObjects, pFormResource); status.RenderObjectList(pPattern->m_pForm, &matrix); m_pDevice->RestoreState(); } m_pDevice->RestoreState(); delete pStates; return; } if (bAligned) { int orig_x = FXSYS_round(mtPattern2Device.e); int orig_y = FXSYS_round(mtPattern2Device.f); min_col = (clip_box.left - orig_x) / width; if (clip_box.left < orig_x) { min_col--; } max_col = (clip_box.right - orig_x) / width; if (clip_box.right <= orig_x) { max_col--; } min_row = (clip_box.top - orig_y) / height; if (clip_box.top < orig_y) { min_row--; } max_row = (clip_box.bottom - orig_y) / height; if (clip_box.bottom <= orig_y) { max_row--; } } FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e; FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f; CFX_DIBitmap* pPatternBitmap = NULL; if (width * height < 16) { CFX_DIBitmap* pEnlargedBitmap = DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern, pObj2Device, 8, 8, m_Options.m_Flags); pPatternBitmap = pEnlargedBitmap->StretchTo(width, height); delete pEnlargedBitmap; } else { pPatternBitmap = DrawPatternBitmap( m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern, pObj2Device, width, height, m_Options.m_Flags); } if (!pPatternBitmap) { m_pDevice->RestoreState(); return; } if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); } FX_ARGB fill_argb = GetFillArgb(pPageObj); int clip_width = clip_box.right - clip_box.left; int clip_height = clip_box.bottom - clip_box.top; CFX_DIBitmap screen; if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) { return; } screen.Clear(0); FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer(); for (int col = min_col; col <= max_col; col++) { for (int row = min_row; row <= max_row; row++) { int start_x, start_y; if (bAligned) { start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left; start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top; } else { FX_FLOAT orig_x = col * pPattern->m_XStep; FX_FLOAT orig_y = row * pPattern->m_YStep; mtPattern2Device.Transform(orig_x, orig_y); start_x = FXSYS_round(orig_x + left_offset) - clip_box.left; start_y = FXSYS_round(orig_y + top_offset) - clip_box.top; } if (width == 1 && height == 1) { if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 || start_y >= clip_box.Height()) { continue; } FX_DWORD* dest_buf = (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y + start_x * 4); if (pPattern->m_bColored) { *dest_buf = *src_buf; } else { *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff); } } else { if (pPattern->m_bColored) { screen.CompositeBitmap(start_x, start_y, width, height, pPatternBitmap, 0, 0); } else { screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap, fill_argb, 0, 0); } } } } CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, FXDIB_BLEND_NORMAL, FALSE); m_pDevice->RestoreState(); delete pPatternBitmap; }

static void DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex triangle[3]) { FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; for (int i = 1; i < 3; i++) { if (min_y > triangle[i].y) { min_y = triangle[i].y; } if (max_y < triangle[i].y) { max_y = triangle[i].y; } } if (min_y == max_y) { return; } int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); if (min_yi < 0) { min_yi = 0; } if (max_yi >= pBitmap->GetHeight()) { max_yi = pBitmap->GetHeight() - 1; } for (int y = min_yi; y <= max_yi; y++) { int nIntersects = 0; FX_FLOAT inter_x[3], r[3], g[3], b[3]; for (int i = 0; i < 3; i++) { CPDF_MeshVertex& vertex1 = triangle[i]; CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; FX_BOOL bIntersect = _GetScanlineIntersect( y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]); if (!bIntersect) { continue; } r[nIntersects] = vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y, vertex2.y - vertex1.y); g[nIntersects] = vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y, vertex2.y - vertex1.y); b[nIntersects] = vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y, vertex2.y - vertex1.y); nIntersects++; } if (nIntersects != 2) { continue; } int min_x, max_x, start_index, end_index; if (inter_x[0] < inter_x[1]) { min_x = (int)FXSYS_floor(inter_x[0]); max_x = (int)FXSYS_ceil(inter_x[1]); start_index = 0; end_index = 1; } else { min_x = (int)FXSYS_floor(inter_x[1]); max_x = (int)FXSYS_ceil(inter_x[0]); start_index = 1; end_index = 0; } int start_x = min_x, end_x = max_x; if (start_x < 0) { start_x = 0; } if (end_x > pBitmap->GetWidth()) { end_x = pBitmap->GetWidth(); } uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x); FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x); FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit; FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit; FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit; for (int x = start_x; x < end_x; x++) { R += r_unit; G += g_unit; B += b_unit; FXARGB_SETDIB(dib_buf, FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); dib_buf += 4; } } }

double _toInteger(double n) { return (n >= 0)? FXSYS_floor(n): -FXSYS_floor(-n); }

void CWeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags) { if (m_pWeightTables) { FX_Free(m_pWeightTables); m_pWeightTables = NULL; } double scale, base; scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); if (dest_len < 0) { base = (FX_FLOAT)(src_len); } else { base = 0; } int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; m_ItemSize = sizeof(int) * 2 + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); m_DestMin = dest_min; if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { return; } m_pWeightTables = FX_AllocNL(FX_BYTE, (dest_max - dest_min) * m_ItemSize + 4); if (m_pWeightTables == NULL) { return; } if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) { PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); double src_pos = dest_pixel * scale + scale / 2 + base; if (flags & FXDIB_INTERPOL) { pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); if (pixel_weights.m_SrcStart < src_min) { pixel_weights.m_SrcStart = src_min; } if (pixel_weights.m_SrcEnd >= src_max) { pixel_weights.m_SrcEnd = src_max - 1; } if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { pixel_weights.m_Weights[0] = 65536; } else { pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536); pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; } } else if (flags & FXDIB_BICUBIC_INTERPOL) { pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); int start = pixel_weights.m_SrcStart - 1; int end = pixel_weights.m_SrcEnd + 1; if (start < src_min) { start = src_min; } if (end >= src_max) { end = src_max - 1; } if (pixel_weights.m_SrcStart < src_min) { src_pos += src_min - pixel_weights.m_SrcStart; pixel_weights.m_SrcStart = src_min; } if (pixel_weights.m_SrcEnd >= src_max) { pixel_weights.m_SrcEnd = src_max - 1; } int weight; weight = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256); if (start == end) { pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; } else if ((start == pixel_weights.m_SrcStart && (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd || end == pixel_weights.m_SrcEnd) && start < end) || (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && end == pixel_weights.m_SrcEnd)) { if (start < pixel_weights.m_SrcStart) { pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; pixel_weights.m_Weights[1] = (SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; } else { if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight]) << 8; pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8; } else { pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; pixel_weights.m_Weights[1] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; } } if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { pixel_weights.m_SrcEnd = end; } if (start < pixel_weights.m_SrcStart) { pixel_weights.m_SrcStart = start; } } else if (start == pixel_weights.m_SrcStart && start < pixel_weights.m_SrcEnd && pixel_weights.m_SrcEnd < end) { pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8; pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8; pixel_weights.m_SrcEnd = end; } else if (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd && pixel_weights.m_SrcEnd == end) { pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; pixel_weights.m_Weights[2] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; pixel_weights.m_SrcStart = start; } else { pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8; pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8; pixel_weights.m_SrcStart = start; pixel_weights.m_SrcEnd = end; } } else { pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos); if (pixel_weights.m_SrcStart < src_min) { pixel_weights.m_SrcStart = src_min; } if (pixel_weights.m_SrcEnd >= src_max) { pixel_weights.m_SrcEnd = src_max - 1; } pixel_weights.m_Weights[0] = 65536; } } return; } for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) { PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); double src_start = dest_pixel * scale + base; double src_end = src_start + scale; int start_i, end_i; if (src_start < src_end) { start_i = (int)FXSYS_floor((FX_FLOAT)src_start); end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); } else { start_i = (int)FXSYS_floor((FX_FLOAT)src_end); end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); } if (start_i < src_min) { start_i = src_min; } if (end_i >= src_max) { end_i = src_max - 1; } if (start_i > end_i) { if (start_i >= src_max) { start_i = src_max - 1; } pixel_weights.m_SrcStart = start_i; pixel_weights.m_SrcEnd = start_i; continue; } pixel_weights.m_SrcStart = start_i; pixel_weights.m_SrcEnd = end_i; for (int j = start_i; j <= end_i; j ++) { double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale); double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); if (dest_start > dest_end) { double temp = dest_start; dest_start = dest_end; dest_end = temp; } double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel); double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end; double weight = area_start >= area_end ? 0.0f : area_end - area_start; if (weight == 0 && j == end_i) { pixel_weights.m_SrcEnd --; break; } pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536)); } } }

int JS_GetSecFromTime(double dt) { return (int)_Mod(FXSYS_floor((double)(dt/1000)), 60); }

int JS_GetMinFromTime(double dt) { return (int)_Mod(FXSYS_floor((double)(dt/(60*1000))), 60); }

int JS_GetHourFromTime(double dt) { return (int)_Mod(FXSYS_floor((double)(dt/(60*60*1000))), 24); }

int _Day(double t) { return (int)FXSYS_floor(t / 86400000); }

int _DayFromYear(int y) { return (int)(365*(y - 1970.0) + FXSYS_floor((y - 1969.0)/4) - FXSYS_floor((y - 1901.0)/100)+FXSYS_floor((y - 1601.0)/400)); }

FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) { int i1, i2; FX_FLOAT d1, d2; switch (op) { case PSOP_ADD: d1 = Pop(); d2 = Pop(); Push(d1 + d2); break; case PSOP_SUB: d2 = Pop(); d1 = Pop(); Push(d1 - d2); break; case PSOP_MUL: d1 = Pop(); d2 = Pop(); Push(d1 * d2); break; case PSOP_DIV: d2 = Pop(); d1 = Pop(); Push(d1 / d2); break; case PSOP_IDIV: i2 = (int)Pop(); i1 = (int)Pop(); Push(i2 ? i1 / i2 : 0); break; case PSOP_MOD: i2 = (int)Pop(); i1 = (int)Pop(); Push(i2 ? i1 % i2 : 0); break; case PSOP_NEG: d1 = Pop(); Push(-d1); break; case PSOP_ABS: d1 = Pop(); Push((FX_FLOAT)FXSYS_fabs(d1)); break; case PSOP_CEILING: d1 = Pop(); Push((FX_FLOAT)FXSYS_ceil(d1)); break; case PSOP_FLOOR: d1 = Pop(); Push((FX_FLOAT)FXSYS_floor(d1)); break; case PSOP_ROUND: d1 = Pop(); Push(FXSYS_round(d1)); break; case PSOP_TRUNCATE: i1 = (int)Pop(); Push(i1); break; case PSOP_SQRT: d1 = Pop(); Push((FX_FLOAT)FXSYS_sqrt(d1)); break; case PSOP_SIN: d1 = Pop(); Push((FX_FLOAT)FXSYS_sin(d1 * FX_PI / 180.0f)); break; case PSOP_COS: d1 = Pop(); Push((FX_FLOAT)FXSYS_cos(d1 * FX_PI / 180.0f)); break; case PSOP_ATAN: d2 = Pop(); d1 = Pop(); d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / FX_PI); if (d1 < 0) { d1 += 360; } Push(d1); break; case PSOP_EXP: d2 = Pop(); d1 = Pop(); Push((FX_FLOAT)FXSYS_pow(d1, d2)); break; case PSOP_LN: d1 = Pop(); Push((FX_FLOAT)FXSYS_log(d1)); break; case PSOP_LOG: d1 = Pop(); Push((FX_FLOAT)FXSYS_log10(d1)); break; case PSOP_CVI: i1 = (int)Pop(); Push(i1); break; case PSOP_CVR: break; case PSOP_EQ: d2 = Pop(); d1 = Pop(); Push((int)(d1 == d2)); break; case PSOP_NE: d2 = Pop(); d1 = Pop(); Push((int)(d1 != d2)); break; case PSOP_GT: d2 = Pop(); d1 = Pop(); Push((int)(d1 > d2)); break; case PSOP_GE: d2 = Pop(); d1 = Pop(); Push((int)(d1 >= d2)); break; case PSOP_LT: d2 = Pop(); d1 = Pop(); Push((int)(d1 < d2)); break; case PSOP_LE: d2 = Pop(); d1 = Pop(); Push((int)(d1 <= d2)); break; case PSOP_AND: i1 = (int)Pop(); i2 = (int)Pop(); Push(i1 & i2); break; case PSOP_OR: i1 = (int)Pop(); i2 = (int)Pop(); Push(i1 | i2); break; case PSOP_XOR: i1 = (int)Pop(); i2 = (int)Pop(); Push(i1 ^ i2); break; case PSOP_NOT: i1 = (int)Pop(); Push((int)!i1); break; case PSOP_BITSHIFT: { int shift = (int)Pop(); int i = (int)Pop(); if (shift > 0) { Push(i << shift); } else { Push(i >> -shift); } break; } case PSOP_TRUE: Push(1); break; case PSOP_FALSE: Push(0); break; case PSOP_POP: Pop(); break; case PSOP_EXCH: d2 = Pop(); d1 = Pop(); Push(d2); Push(d1); break; case PSOP_DUP: d1 = Pop(); Push(d1); Push(d1); break; case PSOP_COPY: { int n = static_cast<int>(Pop()); if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE || n > static_cast<int>(m_StackCount)) break; for (int i = 0; i < n; i++) m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; m_StackCount += n; break; } case PSOP_INDEX: { int n = static_cast<int>(Pop()); if (n < 0 || n >= static_cast<int>(m_StackCount)) break; Push(m_Stack[m_StackCount - n - 1]); break; } case PSOP_ROLL: { int j = static_cast<int>(Pop()); int n = static_cast<int>(Pop()); if (m_StackCount == 0) break; if (n < 0 || n > static_cast<int>(m_StackCount)) break; if (j < 0) { for (int i = 0; i < -j; i++) { FX_FLOAT first = m_Stack[m_StackCount - n]; for (int ii = 0; ii < n - 1; ii++) m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; m_Stack[m_StackCount - 1] = first; } } else { for (int i = 0; i < j; i++) { FX_FLOAT last = m_Stack[m_StackCount - 1]; int ii; for (ii = 0; ii < n - 1; ii++) m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; m_Stack[m_StackCount - ii - 1] = last; } } break; } default: break; } return TRUE; }

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; } } }