Pārlūkot izejas kodu

Implement standard pdf exporting

Wayne 6 gadi atpakaļ
vecāks
revīzija
29a0a32c51

+ 61 - 39
src/main/java/com/bomostory/sceneeditmodule/MovieEditActivity.kt

@@ -28,6 +28,7 @@ import com.bomostory.sceneeditmodule.view.MovieSelectView
 import com.example.exportmedia.MediaHelper
 import com.example.tfat.myapplication.R
 import com.google.gson.Gson
+import io.reactivex.Observable
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.schedulers.Schedulers
 import kotlinx.android.synthetic.main.activity_movie_edit.*
@@ -284,53 +285,31 @@ class MovieEditActivity : AppCompatActivity(),
             exportPdfDialog.onClickPrint = Runnable {
                 when (exportPdfDialog.type) {
                     ExportPdfDialog.Type.Standard -> {
-
+                        val name = "standard_${project?.name}_${System.currentTimeMillis()}.pdf"
+                        if (!Config.PDF_FOLDER.exists()) {
+                            Config.PDF_FOLDER.mkdirs()
+                        }
+                        val file = File(Config.PDF_FOLDER, name)
+                        file.createNewFile()
+                        val observable = PdfMaker.makeStandard(this@MovieEditActivity, project!!, file)
+                        Pair(file, observable)
                     }
                     ExportPdfDialog.Type.Booklet -> {
-                        val name = "bookelet_${project?.name}_${System.currentTimeMillis()}.pdf"
+                        val name = "booklet_${project?.name}_${System.currentTimeMillis()}.pdf"
                         if (!Config.PDF_FOLDER.exists()) {
                             Config.PDF_FOLDER.mkdirs()
                         }
                         val file = File(Config.PDF_FOLDER, name)
                         file.createNewFile()
-                        val pd = ProgressDialog(this@MovieEditActivity).apply {
-                            setCancelable(false)
-                        }
-                        PdfMaker.makeBooklet(this@MovieEditActivity, project!!, file)
-                                .subscribeOn(Schedulers.io())
-                                .observeOn(AndroidSchedulers.mainThread())
-                                .doOnSubscribe { pd.show() }
-                                .doFinally {
-                                    pd.dismiss()
-                                    exportPdfDialog.dismiss()
-                                }
-                                .subscribe({
-                                    val progress = (it * 100).toInt()
-                                    val msg = if (progress >= 100) {
-                                        "processing ..."
-                                    } else {
-                                        "$progress%"
-                                    }
-                                    pd.setMessage(msg)
-                                }, {
-                                }, {
-                                    AlertDialog.Builder(this@MovieEditActivity)
-                                            .setMessage("Complete")
-                                            .setPositiveButton("View") { _, _ ->
-                                                val uri = Uri.parse(file.absolutePath)
-                                                val intent = Intent(Intent.ACTION_VIEW, uri).apply {
-                                                    setDataAndType(uri, "application/pdf")
-                                                }
-                                                if (intent.resolveActivity(packageManager) != null) {
-                                                    Intent.createChooser(intent, "").apply {
-                                                        startActivity(this)
-                                                    }
-                                                } else {
-                                                    Toast.makeText(this@MovieEditActivity, "No app can view pdf", Toast.LENGTH_SHORT).show()
-                                                }
-                                            }.show()
-                                })
+                        val observable = PdfMaker.makeBooklet(this@MovieEditActivity, project!!, file)
+                        Pair(file, observable)
                     }
+                }.apply {
+                    exportPdfFile(second, Runnable {
+                        exportPdfDialog.dismiss()
+                    }, Runnable {
+                        showPdfExportCompleteDialog(first)
+                    })
                 }
             }
         }.show(supportFragmentManager)
@@ -394,4 +373,47 @@ class MovieEditActivity : AppCompatActivity(),
                 })
     }
 
+    private fun exportPdfFile(observable: Observable<Float>, onFinally: Runnable, onComplete: Runnable) {
+        val pd = ProgressDialog(this@MovieEditActivity).apply {
+            setCancelable(false)
+        }
+        observable.subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .doOnSubscribe { pd.show() }
+                .doFinally {
+                    pd.dismiss()
+                    onFinally.run()
+                }
+                .subscribe({
+                    val progress = (it * 100).toInt()
+                    val msg = if (progress >= 100) {
+                        "processing ..."
+                    } else {
+                        "$progress%"
+                    }
+                    pd.setMessage(msg)
+                }, {
+                }, {
+                    onComplete.run()
+                })
+    }
+
+    private fun showPdfExportCompleteDialog(file: File) {
+        AlertDialog.Builder(this@MovieEditActivity)
+                .setMessage("Complete")
+                .setPositiveButton("View") { _, _ ->
+                    val uri = Uri.parse(file.absolutePath)
+                    val intent = Intent(Intent.ACTION_VIEW, uri).apply {
+                        setDataAndType(uri, "application/pdf")
+                    }
+                    if (intent.resolveActivity(packageManager) != null) {
+                        Intent.createChooser(intent, "").apply {
+                            startActivity(this)
+                        }
+                    } else {
+                        Toast.makeText(this@MovieEditActivity, "No app can view pdf", Toast.LENGTH_SHORT).show()
+                    }
+                }.show()
+    }
+
 }

+ 67 - 35
src/main/java/com/bomostory/sceneeditmodule/PdfMaker.kt

@@ -3,12 +3,36 @@ package com.bomostory.sceneeditmodule
 import android.content.Context
 import android.graphics.*
 import com.bomostory.pdfexport.PdfBookWriter
+import com.bomostory.pdfexport.StandardPdfWriter
 import com.bomostory.sceneeditmodule.basicdata.Project
 import com.example.tfat.myapplication.R
 import io.reactivex.Observable
 import java.io.File
 
 object PdfMaker {
+    fun makeStandard(context: Context, project: Project, file: File): Observable<Float> {
+        return Observable.create { emitter ->
+            val total = (2 + project.story?.scenes?.size!!).toFloat()
+            var progress = 0
+            val width = 1920
+            val height = 1080
+            val coverWidth = width / 2
+            emitter.onNext(progress++ / total)
+            val front = drawFrontCover(coverWidth, height, project.name ?: "")
+            emitter.onNext(progress++ / total)
+            val back = drawBackCover(context, coverWidth, height)
+            emitter.onNext(progress++ / total)
+            val standardPdfWriter = StandardPdfWriter(file, front, back)
+            project.story?.scenes?.forEach {
+                val bitmap = SceneDrawer.drawScene(it, 0, width, height) ?: return@forEach
+                standardPdfWriter.addImage(bitmap)
+                emitter.onNext(progress++ / total)
+            }
+            standardPdfWriter.finish()
+            emitter.onComplete()
+        }
+    }
+
     fun makeBooklet(context: Context, project: Project, file: File): Observable<Float> {
         return Observable.create { emitter ->
             val total = (2 + project.story?.scenes?.size!!).toFloat()
@@ -17,45 +41,12 @@ object PdfMaker {
             val height = 1080
             val name = project?.name ?: ""
             val author = project?.author ?: ""
-            val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
-                color = Color.WHITE
-                textSize = 100f
-                textAlign = Paint.Align.CENTER
-                flags += Paint.FAKE_BOLD_TEXT_FLAG
-            }
             emitter.onNext(progress++ / total)
             /** front **/
-            val front = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
-                Canvas(this).apply {
-                    drawColor(Color.parseColor("#faa600"))
-                    val marginBottom = height / 20
-                    val rect = Rect(0, height - height / 3 - marginBottom, width, height - marginBottom)
-                    val p = Paint(Paint.ANTI_ALIAS_FLAG).apply {
-                        color = Color.parseColor("#66ffffff")
-                        style = Paint.Style.FILL_AND_STROKE
-                    }
-                    drawRect(rect, p)
-                    drawText(name, rect.centerX().toFloat(), rect.centerY().toFloat(), paint)
-                }
-            }
+            val front = drawFrontCover(width, height, name)
             emitter.onNext(progress++ / total)
             /** back **/
-            val back = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
-                Canvas(this).apply {
-                    drawColor(Color.parseColor("#faa600"))
-                    val drawable = context.getDrawable(R.drawable.ic_logo_full_white)
-                    val marginBottom = this.height / 10
-                    val w = this.width / 3
-                    val scale = w.toFloat() / drawable.intrinsicWidth.toFloat()
-                    val h = drawable.intrinsicHeight * scale
-                    val left = (this.width - w) / 2
-                    val top = (this.height - h) - marginBottom
-                    val right = (this.width + w) / 2
-                    val bottom = (this.height) - marginBottom
-                    drawable.setBounds(left, top.toInt(), right, bottom)
-                    drawable.draw(this)
-                }
-            }
+            val back = drawBackCover(context, width, height)
             emitter.onNext(progress++ / total)
             /** pages **/
             val pdfBookWriter = PdfBookWriter(file, front, back)
@@ -68,4 +59,45 @@ object PdfMaker {
             emitter.onComplete()
         }
     }
+
+    private fun drawFrontCover(width: Int, height: Int, name: String): Bitmap {
+        val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+            color = Color.WHITE
+            textSize = 100f
+            textAlign = Paint.Align.CENTER
+            flags += Paint.FAKE_BOLD_TEXT_FLAG
+        }
+        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
+            Canvas(this).apply {
+                drawColor(Color.parseColor("#faa600"))
+                val marginBottom = height / 20
+                val rect = Rect(0, height - height / 3 - marginBottom, width, height - marginBottom)
+                val p = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+                    color = Color.parseColor("#66ffffff")
+                    style = Paint.Style.FILL_AND_STROKE
+                }
+                drawRect(rect, p)
+                drawText(name, rect.centerX().toFloat(), rect.centerY().toFloat(), paint)
+            }
+        }
+    }
+
+    private fun drawBackCover(context: Context, width: Int, height: Int): Bitmap {
+        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
+            Canvas(this).apply {
+                drawColor(Color.parseColor("#faa600"))
+                val drawable = context.getDrawable(R.drawable.ic_logo_full_white)
+                val marginBottom = this.height / 10
+                val w = this.width / 3
+                val scale = w.toFloat() / drawable.intrinsicWidth.toFloat()
+                val h = drawable.intrinsicHeight * scale
+                val left = (this.width - w) / 2
+                val top = (this.height - h) - marginBottom
+                val right = (this.width + w) / 2
+                val bottom = (this.height) - marginBottom
+                drawable.setBounds(left, top.toInt(), right, bottom)
+                drawable.draw(this)
+            }
+        }
+    }
 }