사용자 도구

사이트 도구


android:pdfdocument:sectioning
sectioning

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
android:pdfdocument:sectioning [2024/12/16 19:50] 이거니맨android:pdfdocument:sectioning [2024/12/24 20:00] (현재) 이거니맨
줄 50: 줄 50:
 </code> </code>
  
-===== 구역화를 할 떄의 문제점 ===== +===== 구역화를 할 때 고려해야 할 문제점 ===== 
  
 안드로이드의 기본 PDF API(android.graphics.pdf)를 이용하여 pdf문서를 만들고자 할 때의 가장 큰 문제점은, 안드로이드의 기본 PDF API(android.graphics.pdf)를 이용하여 pdf문서를 만들고자 할 때의 가장 큰 문제점은,
줄 61: 줄 61:
  
 <code kotlin> <code kotlin>
- // create new document +// creating PDF Document instance 
- PdfDocument document new PdfDocument();+val pdfDocument: PdfDocument = PdfDocument()
  
- // create a page description +// create a page description 
- PageInfo pageInfo new PageInfo.Builder(1001001).create();+val myPageInfo: PdfDocument.PageInfo = 
 +            PdfDocument.PageInfo.Builder(PDF_PAGE_WIDTHPDF_PAGE_HEIGHTnum).create()
  
- // start a page +// start a page 
- Page page document.startPage(pageInfo);+val newPage: PdfDocument.Page = pdfDocument.startPage(a4Paper(pageNum + 1))
  
- // draw something on the page +// start canvas 
- View content = getContentView(); +val canvas = newPage.canvas 
- content.draw(page.getCanvas());+ 
 +// draw something on the page 
 +canvas.draw(....)
  
  // finish the page  // finish the page
- document.finishPage(page);+pdfDocument.finishPage(page);
  . . .  . . .
- // add more pages+ 
 +// add more pages
  . . .  . . .
- // write the document content +// write the document content 
- document.writeTo(getOutputStream());+pdfDocument.writeTo(getOutputStream());
  
- // close the document +// close the document 
- document.close();+pdfDocument.close();
 </code> </code>
  
  
-==== 2. 비트맵으로 저장하고 그리기 ==== +위와 같이  canvas는  page에서  get하는 것만 가능하고, set은 안된다. 
  
-본문을 비트맵 그림파일의 배열로 저장한 후에, 이 것을 출력하는 방법이 있을 수 다.+따라서 어떤 식으로 하든, 이미 만들어진 canvas를 pdf page에 복사할 가 없다. 
  
-그런데 비트맵 그림은 너무도 당연하게도 확대축소시에 글자가 깨지는 문제점이 생긴다.  
  
-아래 림을 보면 머릿말, 꼬릿말의 폰트와 본문의 폰트 상도가 름을 느낄 수 있다.+래서 고민끝에 생각낸 해결책은 음의 세가지이다.
  
 +첫째, 안드로이드에서 제공하는 pdf graphics api가 아닌,  제3의 라이브러리를 이용하는 것이다. [[https://itextpdf.com/|iText]]라는 라이브러리가 있는데, 찾아보니 이 라이브러리로는 헤더와 푸터를 만들어주었다. 그런데 내가 구현하려고 하는 궁극적인 목적인 '꼬리말에 전체 페이지수와 현재페이지수를 보여주기'는 이 라이브러리로 가능한지가 모르겠다. 무엇보다도, 여기까지 왔는데 외부 라이브러리를 쓴다는건  허탈하기도 할 뿐더러, 무척 자존심이 상하는 일이기도 하다. 
 +
 +둘째, canvas는 비단 pdf page로만 만들 필요가 없다.  canvas만 따로 선언이 가능하다. 그리고 이 경우에는 캔버스가 비트맵을 그려주었다. 이러한 비트맵그림 파일을 pdf의 본문 영역에 그림으로 그려주는 것도 가능하다. 이하에서는 이에 대하여 알아 보도록 하겠다. 다만 후술하겠지만 이 경우에는 문제가 생긴다. 
 +
 +
 +셋째, 본문 영역에 대한 pdf를 만든 후에, 이 작업을 모두 기억했다가 다시 헤더와 푸터가 포함되어 있는 [[android:pdfdocument:commandmirroring|pdf전체를 만들 때에 기억한 작업을 그대로 반복하는 경우]]가 있을 수가 있다. 이렇게 해야만 pdf 파일이 벡터로 저장되어 확대했을 때 글자가 깨지지 않는다. 
 +
 +
 +
 +===== 비트맵으로 저장하고 그리기 =====
 +
 +==== 1. 비트맵 파일 배열 만들기 ====
 +
 +다음과 같이 비트맵 그림으로 저장할 배열을 만들 수 있다. 
 +
 +<code kotlin>
 +    // 비트맵 및 캔버스 리스트 만들기
 +    val bitmapList : ArrayList<Bitmap> = arrayListOf()
 +    val canvasList : ArrayList<Canvas> = arrayListOf<Canvas>()
 +</code>
 +
 +
 +==== 2. 페이지가 바뀔 때마다 비트맵을 새로 만들고 배열에 추가하기 ==== 
 +
 +이런 식으로 페이지가 바뀔 때마다 비트맵을 배열에 추가하는 것이다.
 +
 +<code kotlin>
 +//  캔버스 시작하기
 +fun beginCanvas() {
 +    bitmapList.add(Bitmap.createBitmap(body.Width, body.Height, Bitmap.Config.ARGB_8888))
 +    canvasList.add(Canvas(bitmapList[0]))
 +
 +    pageNum = 0;
 +    totalPOS = POS(0, 0)
 +    currentPOS = POS(0, 0)
 +}
 +
 +// Next Page
 +fun nextPage() {
 +
 +    val newNum = totalPOS.Y / body.Height
 +
 +    if (newNum > pageNum) {
 +        pageNum = newNum
 +        currentPOS.Y = 20
 +
 +        bitmapList.add(Bitmap.createBitmap(body.Width, body.Height, Bitmap.Config.ARGB_8888))
 +        canvasList.add(Canvas(bitmapList[pageNum]))
 +
 +
 +    }
 +}
 +</code>
 +
 +==== 3. 그리기 함수들 ====
 +
 +각 그리기 함수에는 캔버스의 배열 번호를 지정해주면 될 것이다. 
 +
 +예를들면 다음과 같다. 
 +
 +<code kotlin>
 +// Draw Title Text
 +fun titleText(text : String) {
 +
 +    nextPage()
 +    linefeedBig()
 +    canvasList[pageNum].drawText(text, (canvasList[pageNum].width / 2).toFloat(), currentPOS.Y.toFloat(), title)
 +    linefeedBig()
 +}
 +</code>
 +
 +=== 4. PDF 페이지 만들기 ==== 
 +
 +이렇게 만든 그림들을 canvas의 drawbitmap을 이용하여 본문 부분을 비트맵으로 그리면 된다.
 +
 +<code kotlin>
 +// PDF 페이지 만들기
 +fun makePDFDocument() {
 +
 +    for (i in 0 until canvasList.size) {
 +        val newPage: PdfDocument.Page = pdfDocument.startPage(a4Paper(pageNum + 1))
 +
 +        val canvas = newPage.canvas
 +
 +        drawPageHeader(canvas)
 +        canvas.drawBitmap(bitmapList[i], body.rectP.left.toFloat(), body.rectP.top.toFloat(), null)
 +        drawPageFooter(canvas, i + 1)
 +        pdfDocument.finishPage(newPage)
 +
 +    }
 +}
 +</code>
 +
 +
 +==== 5. 헤더와 푸터 ====
 +
 +참고로, 머리말과 꼬리말은 다음과 같이 만들었다.
 +
 +<code kotlin>
 +private fun drawPageHeader(canvas: Canvas) {
 +    canvas.drawText("간이 고소장(모욕)", (PDF_PAGE_WIDTH - 20).toFloat(), (marginTop - 7).toFloat(), textRight)
 +    canvas.drawLine(20f, marginTop - 3f, PDF_PAGE_WIDTH - 20f, marginTop - 3f, linePaint)
 +}
 +
 +private fun drawPageFooter(canvas: Canvas, i : Int) {
 +    canvas.drawLine(20f, PDF_PAGE_HEIGHT - marginBottom + 10f, PDF_PAGE_WIDTH - 20f, PDF_PAGE_HEIGHT - marginBottom + 10f, linePaint)
 +    canvas.drawText( i.toString() + " / " + canvasList.size , (PDF_PAGE_WIDTH - 30).toFloat(), (PDF_PAGE_HEIGHT - marginBottom + 30f), textRight)
 +    canvas.drawText("고소인 : $plaintiffName", marginLeft.toFloat(), (PDF_PAGE_HEIGHT - marginBottom + 30f), cellBodyLeft)
 +}
 +</code>
 +
 +
 +=== 6. 결론 ====
 +
 +이렇게 하면 머릿말과 꼬릿말은 pdf로 그린 것이지만, 본문 부문은 비트맵으로 만든 그림을 그래도 출력한 것이다. 
 +
 +그래서 머릿말과 꼬릿말은 확대를 해도 글자가 깨지지 않지만 본문 부분은 확대를 하면 깨지는 것을 볼 수 있다. 
  
-따라서 다른 방법을 모색해 보아야 한다.  
  
 ^  비트맵으로 그린 본문  ^^ ^  비트맵으로 그린 본문  ^^
 |  {{:android:pdfdocument:bitmap1.jpg?400|bitmap1}}  |  {{:android:pdfdocument:bitmap2.jpg?400|bitmap2}}  | |  {{:android:pdfdocument:bitmap1.jpg?400|bitmap1}}  |  {{:android:pdfdocument:bitmap2.jpg?400|bitmap2}}  |
 +
 +
 +
 +따라서 이러한 방식이 그다지 좋은 것은 아님을 알 수 있다.  
 +
 +이에 지금까지 했던 일을 기억 한 후에 다시 벡터로 그리는 방식을 채택하기로 했다.
 +
 +이에 대해서는 [[android:pdfdocument:commandmirroring|다음 포스팅]]을 참고하라. 
android/pdfdocument/sectioning.1734346220.txt.gz · 마지막으로 수정됨: 2024/12/16 19:50 저자 이거니맨