| // Copyright 2014 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #include "../include/fsdk_define.h" | |
| #include "../include/fsdk_mgr.h" | |
| #include "../include/fsdk_baseannot.h" | |
| //--------------------------------------------------------------------------- | |
| // CPDFSDK_DateTime | |
| //--------------------------------------------------------------------------- | |
| int _gAfxGetTimeZoneInSeconds(FX_CHAR tzhour, FX_BYTE tzminute) | |
| { | |
| return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60); | |
| } | |
| FX_BOOL _gAfxIsLeapYear(FX_SHORT year) | |
| { | |
| return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))); | |
| } | |
| FX_WORD _gAfxGetYearDays(FX_SHORT year) | |
| { | |
| return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365); | |
| } | |
| FX_BYTE _gAfxGetMonthDays(FX_SHORT year, FX_BYTE month) | |
| { | |
| FX_BYTE mDays; | |
| switch (month) | |
| { | |
| case 1: | |
| case 3: | |
| case 5: | |
| case 7: | |
| case 8: | |
| case 10: | |
| case 12: | |
| mDays = 31; | |
| break; | |
| case 4: | |
| case 6: | |
| case 9: | |
| case 11: | |
| mDays = 30; | |
| break; | |
| case 2: | |
| if (_gAfxIsLeapYear(year) == TRUE) | |
| mDays = 29; | |
| else | |
| mDays = 28; | |
| break; | |
| default: | |
| mDays = 0; | |
| break; | |
| } | |
| return mDays; | |
| } | |
| CPDFSDK_DateTime::CPDFSDK_DateTime() | |
| { | |
| ResetDateTime(); | |
| } | |
| CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) | |
| { | |
| ResetDateTime(); | |
| FromPDFDateTimeString(dtStr); | |
| } | |
| CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) | |
| { | |
| operator = (datetime); | |
| } | |
| CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) | |
| { | |
| operator = (st) ; | |
| } | |
| void CPDFSDK_DateTime::ResetDateTime() | |
| { | |
| tzset(); | |
| time_t curTime; | |
| time(&curTime); | |
| struct tm* newtime; | |
| //newtime = gmtime(&curTime); | |
| newtime = localtime(&curTime); | |
| dt.year = newtime->tm_year + 1900; | |
| dt.month = newtime->tm_mon + 1; | |
| dt.day = newtime->tm_mday; | |
| dt.hour = newtime->tm_hour; | |
| dt.minute = newtime->tm_min; | |
| dt.second = newtime->tm_sec; | |
| // dt.tzHour = _timezone / 3600 * -1; | |
| // dt.tzMinute = (abs(_timezone) % 3600) / 60; | |
| } | |
| CPDFSDK_DateTime& CPDFSDK_DateTime::operator = (const CPDFSDK_DateTime& datetime) | |
| { | |
| FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME)); | |
| return *this; | |
| } | |
| CPDFSDK_DateTime& CPDFSDK_DateTime::operator = (const FX_SYSTEMTIME& st) | |
| { | |
| tzset(); | |
| dt.year = (FX_SHORT)st.wYear; | |
| dt.month = (FX_BYTE)st.wMonth; | |
| dt.day = (FX_BYTE)st.wDay; | |
| dt.hour = (FX_BYTE)st.wHour; | |
| dt.minute = (FX_BYTE)st.wMinute; | |
| dt.second = (FX_BYTE)st.wSecond; | |
| // dt.tzHour = _timezone / 3600 * -1; | |
| // dt.tzMinute = (abs(_timezone) % 3600) / 60; | |
| return *this; | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator == (CPDFSDK_DateTime& datetime) | |
| { | |
| return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0); | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator != (CPDFSDK_DateTime& datetime) | |
| { | |
| return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) != 0); | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator > (CPDFSDK_DateTime& datetime) | |
| { | |
| CPDFSDK_DateTime dt1 = ToGMT(); | |
| CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
| int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
| int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second; | |
| int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
| int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second; | |
| if (d1 > d3) return TRUE; | |
| if (d2 > d4) return TRUE; | |
| return FALSE; | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator >= (CPDFSDK_DateTime& datetime) | |
| { | |
| CPDFSDK_DateTime dt1 = ToGMT(); | |
| CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
| int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
| int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second; | |
| int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
| int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second; | |
| if (d1 >= d3) return TRUE; | |
| if (d2 >= d4) return TRUE; | |
| return FALSE; | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator < (CPDFSDK_DateTime& datetime) | |
| { | |
| CPDFSDK_DateTime dt1 = ToGMT(); | |
| CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
| int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
| int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second; | |
| int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
| int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second; | |
| if (d1 < d3) return TRUE; | |
| if (d2 < d4) return TRUE; | |
| return FALSE; | |
| } | |
| FX_BOOL CPDFSDK_DateTime::operator <= (CPDFSDK_DateTime& datetime) | |
| { | |
| CPDFSDK_DateTime dt1 = ToGMT(); | |
| CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
| int d1 = (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
| int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | (int)dt1.dt.second; | |
| int d3 = (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
| int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | (int)dt2.dt.second; | |
| if (d1 <= d3) return TRUE; | |
| if (d2 <= d4) return TRUE; | |
| return FALSE; | |
| } | |
| CPDFSDK_DateTime::operator time_t() | |
| { | |
| struct tm newtime; | |
| newtime.tm_year = dt.year - 1900; | |
| newtime.tm_mon = dt.month - 1; | |
| newtime.tm_mday = dt.day; | |
| newtime.tm_hour = dt.hour; | |
| newtime.tm_min = dt.minute; | |
| newtime.tm_sec = dt.second; | |
| return mktime(&newtime); | |
| } | |
| CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(const CFX_ByteString& dtStr) | |
| { | |
| int strLength = dtStr.GetLength(); | |
| if (strLength > 0) | |
| { | |
| int i = 0; | |
| int j, k; | |
| FX_CHAR ch; | |
| while (i < strLength) | |
| { | |
| ch = dtStr[i]; | |
| if (ch >= '0' && ch <= '9') break; | |
| i ++; | |
| } | |
| if (i >= strLength) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 4) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.year = (FX_SHORT)k; | |
| if (i >= strLength || j < 4) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.month = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.day = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.hour = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.minute = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.second = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| ch = dtStr[i ++]; | |
| if (ch != '-' && ch != '+') return *this; | |
| if (ch == '-') | |
| dt.tzHour = -1; | |
| else | |
| dt.tzHour = 1; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.tzHour *= (FX_CHAR)k; | |
| if (i >= strLength || j < 2) return *this; | |
| ch = dtStr[i ++]; | |
| if (ch != '\'') return *this; | |
| j = 0; | |
| k = 0; | |
| while (i < strLength && j < 2) | |
| { | |
| ch = dtStr[i]; | |
| k = k * 10 + ch - '0'; | |
| j ++; | |
| if (ch < '0' || ch > '9') break; | |
| i ++; | |
| } | |
| dt.tzMinute = (FX_BYTE)k; | |
| if (i >= strLength || j < 2) return *this; | |
| } | |
| return *this; | |
| } | |
| CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() | |
| { | |
| CFX_ByteString str1; | |
| str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); | |
| if (dt.tzHour < 0) | |
| str1 += "-"; | |
| else | |
| str1 += "+"; | |
| CFX_ByteString str2; | |
| str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute); | |
| return str1 + str2; | |
| } | |
| CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() | |
| { | |
| CFX_ByteString dtStr; | |
| char tempStr[32]; | |
| sprintf(tempStr, "D:%04d%02d%02d%02d%02d%02d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); | |
| dtStr = CFX_ByteString(tempStr); | |
| if (dt.tzHour < 0) | |
| dtStr += CFX_ByteString("-"); | |
| else | |
| dtStr += CFX_ByteString("+"); | |
| sprintf(tempStr, "%02d'%02d'", abs(dt.tzHour), dt.tzMinute); | |
| dtStr += CFX_ByteString(tempStr); | |
| return dtStr; | |
| } | |
| void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) | |
| { | |
| CPDFSDK_DateTime dt = *this; | |
| time_t t = (time_t)dt; | |
| struct tm* pTime = localtime(&t); | |
| if(pTime){ | |
| st.wYear = (FX_WORD)pTime->tm_year + 1900; | |
| st.wMonth = (FX_WORD)pTime->tm_mon + 1; | |
| st.wDay = (FX_WORD)pTime->tm_mday; | |
| st.wDayOfWeek = (FX_WORD)pTime->tm_wday; | |
| st.wHour = (FX_WORD)pTime->tm_hour; | |
| st.wMinute = (FX_WORD)pTime->tm_min; | |
| st.wSecond = (FX_WORD)pTime->tm_sec; | |
| st.wMilliseconds = 0; | |
| } | |
| } | |
| CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() | |
| { | |
| CPDFSDK_DateTime dt = *this; | |
| dt.AddSeconds(-_gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute)); | |
| dt.dt.tzHour = 0; | |
| dt.dt.tzMinute = 0; | |
| return dt; | |
| } | |
| CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) | |
| { | |
| if (days == 0) return *this; | |
| FX_SHORT y = dt.year, yy; | |
| FX_BYTE m = dt.month; | |
| FX_BYTE d = dt.day; | |
| int mdays, ydays, ldays; | |
| ldays = days; | |
| if (ldays > 0) | |
| { | |
| yy = y; | |
| if (((FX_WORD)m * 100 + d) > 300) yy ++; | |
| ydays = _gAfxGetYearDays(yy); | |
| while (ldays >= ydays) | |
| { | |
| y ++; | |
| ldays -= ydays; | |
| yy ++; | |
| mdays = _gAfxGetMonthDays(y, m); | |
| if (d > mdays) | |
| { | |
| m ++; | |
| d -= mdays; | |
| } | |
| ydays = _gAfxGetYearDays(yy); | |
| } | |
| mdays = _gAfxGetMonthDays(y, m) - d + 1; | |
| while (ldays >= mdays) | |
| { | |
| ldays -= mdays; | |
| m ++; | |
| d = 1; | |
| mdays = _gAfxGetMonthDays(y, m); | |
| } | |
| d += ldays; | |
| } | |
| else | |
| { | |
| ldays *= -1; | |
| yy = y; | |
| if (((FX_WORD)m * 100 + d) < 300) yy --; | |
| ydays = _gAfxGetYearDays(yy); | |
| while (ldays >= ydays) | |
| { | |
| y --; | |
| ldays -= ydays; | |
| yy --; | |
| mdays = _gAfxGetMonthDays(y, m); | |
| if (d > mdays) | |
| { | |
| m ++; | |
| d -= mdays; | |
| } | |
| ydays = _gAfxGetYearDays(yy); | |
| } | |
| while (ldays >= d) | |
| { | |
| ldays -= d; | |
| m --; | |
| mdays = _gAfxGetMonthDays(y, m); | |
| d = mdays; | |
| } | |
| d -= ldays; | |
| } | |
| dt.year = y; | |
| dt.month = m; | |
| dt.day = d; | |
| return *this; | |
| } | |
| CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) | |
| { | |
| if (seconds == 0) return *this; | |
| int n; | |
| int days; | |
| n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds; | |
| if (n < 0) | |
| { | |
| days = (n - 86399) / 86400; | |
| n -= days * 86400; | |
| } | |
| else | |
| { | |
| days = n / 86400; | |
| n %= 86400; | |
| } | |
| dt.hour = (FX_BYTE)(n / 3600); | |
| dt.hour %= 24; | |
| n %= 3600; | |
| dt.minute = (FX_BYTE)(n / 60); | |
| dt.second = (FX_BYTE)(n % 60); | |
| if (days != 0) AddDays(days); | |
| return *this; | |
| } | |
| //--------------------------------------------------------------------------- | |
| // CPDFSDK_Annot | |
| //--------------------------------------------------------------------------- | |
| CPDFSDK_Annot::CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView) : | |
| m_pAnnot(pAnnot), | |
| m_pPageView(pPageView), | |
| m_bSelected(FALSE), | |
| m_nTabOrder(-1) | |
| { | |
| } | |
| CPDFSDK_Annot::~CPDFSDK_Annot() | |
| { | |
| m_pAnnot = NULL; | |
| m_pPageView = NULL; | |
| } | |
| CPDF_Annot* CPDFSDK_Annot::GetPDFAnnot() | |
| { | |
| return m_pAnnot; | |
| } | |
| FX_DWORD CPDFSDK_Annot::GetFlags() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| return m_pAnnot->GetFlags(); | |
| } | |
| void CPDFSDK_Annot::SetPage(CPDFSDK_PageView* pPageView) | |
| { | |
| m_pPageView = pPageView; | |
| } | |
| CPDFSDK_PageView* CPDFSDK_Annot::GetPageView() | |
| { | |
| return m_pPageView; | |
| } | |
| FX_BOOL CPDFSDK_Annot::IsSelected() | |
| { | |
| return m_bSelected; | |
| } | |
| void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) | |
| { | |
| m_bSelected = bSelected; | |
| } | |
| // Tab Order | |
| int CPDFSDK_Annot::GetTabOrder() | |
| { | |
| return m_nTabOrder; | |
| } | |
| void CPDFSDK_Annot::SetTabOrder(int iTabOrder) | |
| { | |
| m_nTabOrder = iTabOrder; | |
| } | |
| CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| return m_pAnnot->m_pAnnotDict; | |
| } | |
| void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| ASSERT(rect.right - rect.left >= GetMinWidth()); | |
| ASSERT(rect.top - rect.bottom >= GetMinHeight()); | |
| m_pAnnot->m_pAnnotDict->SetAtRect("Rect", rect); | |
| } | |
| CPDF_Rect CPDFSDK_Annot::GetRect() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| CPDF_Rect rect; | |
| m_pAnnot->GetRect(rect); | |
| return rect; | |
| } | |
| CFX_ByteString CPDFSDK_Annot::GetType() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| return m_pAnnot->GetSubType(); | |
| } | |
| CFX_ByteString CPDFSDK_Annot::GetSubType() const | |
| { | |
| return ""; | |
| } | |
| void CPDFSDK_Annot::ResetAppearance() | |
| { | |
| ASSERT(FALSE); | |
| } | |
| void CPDFSDK_Annot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device, | |
| CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions) | |
| { | |
| ASSERT(m_pPageView != NULL); | |
| ASSERT(m_pAnnot != NULL); | |
| m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, mode, pOptions); | |
| } | |
| FX_BOOL CPDFSDK_Annot::IsAppearanceValid() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetDict("AP") != NULL; | |
| } | |
| FX_BOOL CPDFSDK_Annot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Dictionary* pAP = m_pAnnot->m_pAnnotDict->GetDict("AP"); | |
| if (pAP == NULL) return FALSE; | |
| // Choose the right sub-ap | |
| const FX_CHAR* ap_entry = "N"; | |
| if (mode == CPDF_Annot::Down) | |
| ap_entry = "D"; | |
| else if (mode == CPDF_Annot::Rollover) | |
| ap_entry = "R"; | |
| if (!pAP->KeyExist(ap_entry)) | |
| ap_entry = "N"; | |
| // Get the AP stream or subdirectory | |
| CPDF_Object* psub = pAP->GetElementValue(ap_entry); | |
| if (psub == NULL) return FALSE; | |
| return TRUE; | |
| } | |
| void CPDFSDK_Annot::DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device, | |
| const CPDF_RenderOptions* pOptions) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions); | |
| } | |
| void CPDFSDK_Annot::ClearCachedAP() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| m_pAnnot->ClearCachedAP(); | |
| } | |
| void CPDFSDK_Annot::SetContents(const CFX_WideString& sContents) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| if (sContents.IsEmpty()) | |
| m_pAnnot->m_pAnnotDict->RemoveAt("Contents"); | |
| else | |
| m_pAnnot->m_pAnnotDict->SetAtString("Contents", PDF_EncodeText(sContents)); | |
| } | |
| CFX_WideString CPDFSDK_Annot::GetContents() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetUnicodeText("Contents"); | |
| } | |
| void CPDFSDK_Annot::SetAnnotName(const CFX_WideString& sName) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| if (sName.IsEmpty()) | |
| m_pAnnot->m_pAnnotDict->RemoveAt("NM"); | |
| else | |
| m_pAnnot->m_pAnnotDict->SetAtString("NM", PDF_EncodeText(sName)); | |
| } | |
| CFX_WideString CPDFSDK_Annot::GetAnnotName() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetUnicodeText("NM"); | |
| } | |
| void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDFSDK_DateTime dt(st); | |
| CFX_ByteString str = dt.ToPDFDateTimeString(); | |
| if (str.IsEmpty()) | |
| m_pAnnot->m_pAnnotDict->RemoveAt("M"); | |
| else | |
| m_pAnnot->m_pAnnotDict->SetAtString("M", str); | |
| } | |
| FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| FX_SYSTEMTIME systime; | |
| CFX_ByteString str = m_pAnnot->m_pAnnotDict->GetString("M"); | |
| CPDFSDK_DateTime dt(str); | |
| dt.ToSystemTime(systime); | |
| return systime; | |
| } | |
| void CPDFSDK_Annot::SetFlags(int nFlags) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| m_pAnnot->m_pAnnotDict->SetAtInteger("F", nFlags); | |
| } | |
| int CPDFSDK_Annot::GetFlags() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetInteger("F"); | |
| } | |
| void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| if (str.IsEmpty()) | |
| m_pAnnot->m_pAnnotDict->RemoveAt("AS"); | |
| else | |
| m_pAnnot->m_pAnnotDict->SetAtString("AS", str); | |
| } | |
| CFX_ByteString CPDFSDK_Annot::GetAppState() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetString("AS"); | |
| } | |
| void CPDFSDK_Annot::SetStructParent(int key) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| m_pAnnot->m_pAnnotDict->SetAtInteger("StructParent", key); | |
| } | |
| int CPDFSDK_Annot::GetStructParent() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetInteger("StructParent"); | |
| } | |
| //border | |
| void CPDFSDK_Annot::SetBorderWidth(int nWidth) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border"); | |
| if (pBorder) | |
| { | |
| pBorder->SetAt(2, FX_NEW CPDF_Number(nWidth)); | |
| } | |
| else | |
| { | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (!pBSDict) | |
| { | |
| pBSDict = FX_NEW CPDF_Dictionary; | |
| m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict); | |
| } | |
| pBSDict->SetAtInteger("W", nWidth); | |
| } | |
| } | |
| int CPDFSDK_Annot::GetBorderWidth() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border"); | |
| if (pBorder) | |
| { | |
| return pBorder->GetInteger(2); | |
| } | |
| else | |
| { | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (pBSDict) | |
| { | |
| return pBSDict->GetInteger("W", 1); | |
| } | |
| } | |
| return 1; | |
| } | |
| void CPDFSDK_Annot::SetBorderStyle(int nStyle) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (!pBSDict) | |
| { | |
| pBSDict = FX_NEW CPDF_Dictionary; | |
| m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict); | |
| } | |
| switch (nStyle) | |
| { | |
| case BBS_SOLID: | |
| pBSDict->SetAtName("S", "S"); | |
| break; | |
| case BBS_DASH: | |
| pBSDict->SetAtName("S", "D"); | |
| break; | |
| case BBS_BEVELED: | |
| pBSDict->SetAtName("S", "B"); | |
| break; | |
| case BBS_INSET: | |
| pBSDict->SetAtName("S", "I"); | |
| break; | |
| case BBS_UNDERLINE: | |
| pBSDict->SetAtName("S", "U"); | |
| break; | |
| } | |
| } | |
| int CPDFSDK_Annot::GetBorderStyle() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (pBSDict) | |
| { | |
| CFX_ByteString sBorderStyle = pBSDict->GetString("S", "S"); | |
| if (sBorderStyle == "S") return BBS_SOLID; | |
| if (sBorderStyle == "D") return BBS_DASH; | |
| if (sBorderStyle == "B") return BBS_BEVELED; | |
| if (sBorderStyle == "I") return BBS_INSET; | |
| if (sBorderStyle == "U") return BBS_UNDERLINE; | |
| } | |
| CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border"); | |
| if (pBorder) | |
| { | |
| if (pBorder->GetCount() >= 4) | |
| { | |
| CPDF_Array *pDP = pBorder->GetArray(3); | |
| if (pDP && pDP->GetCount() > 0) | |
| return BBS_DASH; | |
| } | |
| } | |
| return BBS_SOLID; | |
| } | |
| void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (!pBSDict) | |
| { | |
| pBSDict = FX_NEW CPDF_Dictionary; | |
| m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict); | |
| } | |
| CPDF_Array* pArray = FX_NEW CPDF_Array; | |
| for (int i=0,sz=array.GetSize(); i<sz; i++) | |
| { | |
| pArray->AddInteger(array[i]); | |
| } | |
| pBSDict->SetAt("D", pArray); | |
| } | |
| void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Array* pDash = NULL; | |
| CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border"); | |
| if (pBorder) | |
| { | |
| pDash = pBorder->GetArray(3); | |
| } | |
| else | |
| { | |
| CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); | |
| if (pBSDict) | |
| { | |
| pDash = pBSDict->GetArray("D"); | |
| } | |
| } | |
| if (pDash) | |
| { | |
| for (int i=0,sz=pDash->GetCount(); i<sz; i++) | |
| { | |
| array.Add(pDash->GetInteger(i)); | |
| } | |
| } | |
| } | |
| void CPDFSDK_Annot::SetColor(FX_COLORREF color) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Array* pArray = FX_NEW CPDF_Array; | |
| pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f); | |
| pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f); | |
| pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f); | |
| m_pAnnot->m_pAnnotDict->SetAt("C", pArray); | |
| } | |
| void CPDFSDK_Annot::RemoveColor() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| m_pAnnot->m_pAnnotDict->RemoveAt("C") ; | |
| } | |
| FX_BOOL CPDFSDK_Annot::GetColor(FX_COLORREF& color) const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| if (CPDF_Array* pEntry = m_pAnnot->m_pAnnotDict->GetArray("C")) | |
| { | |
| int nCount = pEntry->GetCount(); | |
| if (nCount == 1) | |
| { | |
| FX_FLOAT g = pEntry->GetNumber(0) * 255; | |
| color = FXSYS_RGB((int)g, (int)g, (int)g); | |
| return TRUE; | |
| } | |
| else if (nCount == 3) | |
| { | |
| FX_FLOAT r = pEntry->GetNumber(0) * 255; | |
| FX_FLOAT g = pEntry->GetNumber(1) * 255; | |
| FX_FLOAT b = pEntry->GetNumber(2) * 255; | |
| color = FXSYS_RGB((int)r, (int)g, (int)b); | |
| return TRUE; | |
| } | |
| else if (nCount == 4) | |
| { | |
| FX_FLOAT c = pEntry->GetNumber(0); | |
| FX_FLOAT m = pEntry->GetNumber(1); | |
| FX_FLOAT y = pEntry->GetNumber(2); | |
| FX_FLOAT k = pEntry->GetNumber(3); | |
| FX_FLOAT r = 1.0f - FX_MIN(1.0f, c + k); | |
| FX_FLOAT g = 1.0f - FX_MIN(1.0f, m + k); | |
| FX_FLOAT b = 1.0f - FX_MIN(1.0f, y + k); | |
| color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255)); | |
| return TRUE; | |
| } | |
| } | |
| return FALSE; | |
| } | |
| void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, | |
| const CPDF_Matrix& matrix, const CFX_ByteString& sContents, | |
| const CFX_ByteString& sAPState) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP"); | |
| if (!pAPDict) | |
| { | |
| pAPDict = FX_NEW CPDF_Dictionary; | |
| m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict); | |
| } | |
| CPDF_Stream* pStream = NULL; | |
| CPDF_Dictionary* pParentDict = NULL; | |
| if (sAPState.IsEmpty()) | |
| { | |
| pParentDict = pAPDict; | |
| pStream = pAPDict->GetStream(sAPType); | |
| } | |
| else | |
| { | |
| CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType); | |
| if (!pAPTypeDict) | |
| { | |
| pAPTypeDict = FX_NEW CPDF_Dictionary; | |
| pAPDict->SetAt(sAPType, pAPTypeDict); | |
| } | |
| pParentDict = pAPTypeDict; | |
| pStream = pAPTypeDict->GetStream(sAPState); | |
| } | |
| if (!pStream) | |
| { | |
| ASSERT(m_pPageView != NULL); | |
| CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); | |
| ASSERT(pDoc != NULL); | |
| pStream = FX_NEW CPDF_Stream(NULL, 0, NULL); | |
| FX_INT32 objnum = pDoc->AddIndirectObject(pStream); | |
| //pAPDict->SetAtReference(sAPType, pDoc, objnum); | |
| ASSERT(pParentDict != NULL); | |
| pParentDict->SetAtReference(sAPType, pDoc, objnum); | |
| } | |
| CPDF_Dictionary * pStreamDict = pStream->GetDict(); | |
| if (!pStreamDict) | |
| { | |
| pStreamDict = FX_NEW CPDF_Dictionary; | |
| pStreamDict->SetAtName("Type", "XObject"); | |
| pStreamDict->SetAtName("Subtype", "Form"); | |
| pStreamDict->SetAtInteger("FormType", 1); | |
| pStream->InitStream(NULL,0,pStreamDict); | |
| } | |
| if (pStreamDict) | |
| { | |
| pStreamDict->SetAtMatrix("Matrix",matrix); | |
| pStreamDict->SetAtRect("BBox", rcBBox); | |
| } | |
| pStream->SetData((FX_BYTE*)(FX_LPCSTR)sContents, sContents.GetLength(), FALSE, FALSE); | |
| } | |
| #define BA_ANNOT_MINWIDTH 1 | |
| #define BA_ANNOT_MINHEIGHT 1 | |
| FX_FLOAT CPDFSDK_Annot::GetMinWidth() const | |
| { | |
| return BA_ANNOT_MINWIDTH; | |
| } | |
| FX_FLOAT CPDFSDK_Annot::GetMinHeight() const | |
| { | |
| return BA_ANNOT_MINHEIGHT; | |
| } | |
| FX_BOOL CPDFSDK_Annot::CreateFormFiller() | |
| { | |
| return TRUE; | |
| } | |
| FX_BOOL CPDFSDK_Annot::IsVisible() const | |
| { | |
| int nFlags = GetFlags(); | |
| return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || (nFlags & ANNOTFLAG_NOVIEW)); | |
| } | |
| CPDF_Action CPDFSDK_Annot::GetAction() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetDict("A"); | |
| } | |
| void CPDFSDK_Annot::SetAction(const CPDF_Action& action) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| ASSERT(action != NULL); | |
| if ((CPDF_Action&)action != m_pAnnot->m_pAnnotDict->GetDict("A")) | |
| { | |
| CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); | |
| ASSERT(pDoc != NULL); | |
| if (action.m_pDict && (action.m_pDict->GetObjNum() == 0)) | |
| pDoc->AddIndirectObject(action.m_pDict); | |
| m_pAnnot->m_pAnnotDict->SetAtReference("A", pDoc, action.m_pDict->GetObjNum()); | |
| } | |
| } | |
| void CPDFSDK_Annot::RemoveAction() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| m_pAnnot->m_pAnnotDict->RemoveAt("A"); | |
| } | |
| CPDF_AAction CPDFSDK_Annot::GetAAction() const | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| return m_pAnnot->m_pAnnotDict->GetDict("AA"); | |
| } | |
| void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa) | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| ASSERT(aa != NULL); | |
| if ((CPDF_AAction&)aa != m_pAnnot->m_pAnnotDict->GetDict("AA")) | |
| m_pAnnot->m_pAnnotDict->SetAt("AA", (CPDF_AAction&)aa); | |
| } | |
| void CPDFSDK_Annot::RemoveAAction() | |
| { | |
| ASSERT(m_pAnnot != NULL); | |
| ASSERT(m_pAnnot->m_pAnnotDict != NULL); | |
| m_pAnnot->m_pAnnotDict->RemoveAt("AA"); | |
| } | |
| CPDF_Action CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT) | |
| { | |
| CPDF_AAction AAction = GetAAction(); | |
| if (AAction.ActionExist(eAAT)) | |
| { | |
| return AAction.GetAction(eAAT); | |
| } | |
| else if (eAAT == CPDF_AAction::ButtonUp) | |
| { | |
| return GetAction(); | |
| } | |
| return NULL; | |
| } | |
| void CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions) | |
| { | |
| m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal); | |
| m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, CPDF_Annot::Normal, NULL); | |
| return ; | |
| } | |
| CPDF_Page* CPDFSDK_Annot::GetPDFPage() | |
| { | |
| if(m_pPageView) | |
| return m_pPageView->GetPDFPage(); | |
| return NULL; | |
| } | |