﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-feixuwu-随笔分类-PSP开发</title><link>http://www.cppblog.com/feixuwu/category/14414.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 04 Aug 2010 11:44:11 GMT</lastBuildDate><pubDate>Wed, 04 Aug 2010 11:44:11 GMT</pubDate><ttl>60</ttl><item><title>BOOR读pdf内存问题解决</title><link>http://www.cppblog.com/feixuwu/archive/2010/08/04/122227.html</link><dc:creator>feixuwu</dc:creator><author>feixuwu</author><pubDate>Wed, 04 Aug 2010 09:41:00 GMT</pubDate><guid>http://www.cppblog.com/feixuwu/archive/2010/08/04/122227.html</guid><wfw:comment>http://www.cppblog.com/feixuwu/comments/122227.html</wfw:comment><comments>http://www.cppblog.com/feixuwu/archive/2010/08/04/122227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/feixuwu/comments/commentRss/122227.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/feixuwu/services/trackbacks/122227.html</trackback:ping><description><![CDATA[&nbsp; 在前面的文章里，我发布了修改版的boor到http://download.csdn.net/source/2578241
,<br>支持中文pdf和中文txt,能正确显示中文目录。<br>
<h1><br></h1>
<h1>问题<br></h1>
不过，有的朋友反映打开大的pdf文件时，容易死机。<br>这几天看了下，果然发现问题了。 为了加快读取pdf页面速度，bookr一开始就加载了所有的pageTree到内存中，<br>这样显示特定页面的时候，就无需查找该页面的PageObject了，这在PC机上一般没什么问题，PC机有虚拟内存，即使pdf文件很大，无非是加载pageTree慢点，<br>不过在PSP上就不行了，PSP的内存是有限的，而且没有虚拟内存，所以如果PageTree很大，那么很可能会导致内存不够，直接死机了。。。。<br>
<h1><br></h1>
<h1>解决办法</h1>
解决办法其实也很简单，bookr启动的时候不加载PageTree，而是在每次显示的时候，从Root开始便利PageTree查询PageObject对象，任意一时刻，内存中只有一个PageObject对象。<br>这样就就基本解决了内存问题。下一个问题是查询效率的问题，这个问题其实不那么严重，PageTree本来就是一个树形结构，pdf的PageObject查询可以优化成一个树查询，这样应该会很快，实际编码测试，<br>根本感觉不到修改前后翻页速度有明显变化。<br>修改后用 金庸全集三联版.pdf(48.6M)测试OK。<br><br>
<h1>下载</h1>
&nbsp; 1、下载http://download.csdn.net/source/2578241&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 解压到psp/game目录下。<br>&nbsp; 2、从http://www.cppblog.com/Files/feixuwu/EBOOT.rar
下载，解压后，覆盖原来bookr目录下的EBOOT.PBP文件即可。<br><br><br>     <img src ="http://www.cppblog.com/feixuwu/aggbug/122227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/feixuwu/" target="_blank">feixuwu</a> 2010-08-04 17:41 <a href="http://www.cppblog.com/feixuwu/archive/2010/08/04/122227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PSP版本Bookr修改支持中文</title><link>http://www.cppblog.com/feixuwu/archive/2010/07/26/121324.html</link><dc:creator>feixuwu</dc:creator><author>feixuwu</author><pubDate>Mon, 26 Jul 2010 13:41:00 GMT</pubDate><guid>http://www.cppblog.com/feixuwu/archive/2010/07/26/121324.html</guid><wfw:comment>http://www.cppblog.com/feixuwu/comments/121324.html</wfw:comment><comments>http://www.cppblog.com/feixuwu/archive/2010/07/26/121324.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/feixuwu/comments/commentRss/121324.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/feixuwu/services/trackbacks/121324.html</trackback:ping><description><![CDATA[&nbsp; PSP上的阅读软件我所知道的有bookr和XReader（没用过）等，我比较喜欢bookr，不过bookr在阅读很多pdf时，中文会显示成乱码，阅读txt时，根本就无法显示中文，<br>这确实很让人不爽。<br>过年前闲着没事，顺便解决了bookr中文问题，本文记录了那段时间的工作：如何从官方版bookr修改，解决pdf中文乱码问题，支持txt中文、中文目录显示的问题，抛砖引玉和大家分享下整个的思路<br>和问题的解决方式，解决过程比较丑陋，希望高手多多指点。<br>貌似这里不能贴超过2M的附件，这里就不贴出修改后的bookr的发布文件了，在PSP2000测试通过，最近也一直在用,需要的同学可以email问我要。<br>注：已经上传到csdn:http://download.csdn.net/source/2578241
<br>内置了少量字体，大家可以自行扩展字体。<br>
<h1><br></h1>
<h1>准备工作</h1>
&nbsp; 1、搭建PSP开发环境。sourceforge上集成的安装包，下载下来直接安装即可，这里不多说了。<br>&nbsp; 2、下载bookr源码，我下载的是0.7.1版本。可以用SVN下载最新的，也可以在sourceForge下载打包的源码包。<br><br>
<h1>解决PDF中文问题</h1>
&nbsp; bookr的代码结果很清晰，由于是用c++开发的，所以代码很好理解，BKLayer 是基础的显示类，BKDocument是基础的文档处理类。<br>bookr支持pdf、txt、html和 PalmDoc(我没用过这种)，分别由从BKDocument的派生类来处理。<br>pdf是由BKPDF来处理的。解决pdf中文问题的关键就在BKPDF类了。<br><br>
<h2>&nbsp;&nbsp; 1、如何调试</h2>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PSP开发首先遇到的问题是调试，PSP并不能实时调试，这确实是个问题。好在Bookr源码级支持了跨平台，在windows下，使用Makefile.cygwin
就可以编译一个windows版本<br>的Bookr了。一般来说，在windows下bookr运行正常，大致在PSP上的版本也是正常的，当然，在细节上其实是有差别的。另外，还可以通过日志来实现跟踪。<br><br>
<h2>&nbsp;&nbsp; 2、解决字体问题</h2>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际上，有些中文pdf用bookr打开时是正常的，比如Programming_In_Lua.pdf,但是在打开经常温习的金庸全集的时候，就出现乱码了。<br>注意到Bookr的pdf显示其实是主要是mudpf来实现的。那么bookr中文显示问题到底是bookr自身的还是mupdf的呢？<br>为了确认这个问题，先从sourceforge下载mupdf，建立一个vs2005的项目，编译，OK，可以运行了，打开金庸全集一看，还是乱码，这下基本可以确认，这个<br>问题是从mupdf就存在了。要定位中文显示乱码的问题，自然需要了解pdf的内部格式，从adobe的官网下载了最新的pdf手册，打开一看，一共700多页。。。<br>好在我们不需要从头开始阅读，只要挑关键的地方看就可以了，中文问题一般是因为字体引起的。<br><br>所以我们可以直接挑Text的字体相关部分看。<br>mupdf的字体加载在pdf_loadfont里，从pdf手册可知，pdf支持了若干种字体，反正我是没什么耐心看下去，直接打开金庸全集单步调试了下，<br>
发现问题在TrueType字体的加载里，TrueType字体的加载是loadsimplefont来处理的，通过跟踪可知，在获取字体的FontDescriptor的时候失败了，然后就是用内置的默认字体来处理了。<br>默认字体都不支持中文，所以自然就显示成乱码了。<br>最简单的办法就是只要是TrueType字体，不管具体是什么字体，都强制从硬盘加载一种指定字体（例如黑体），当然，这样会导致我们看到的pdf和实际应该显示的样子有差别，只有一种字体了。<br>让我们先这样试试吧：在发现pdf_loadfontdescriptor
加载失败后，强制用loadCustomFont
加载硬盘指定字体"font/simhei.ttf",这样字体加载的问题貌似解决了。<br>编译，运行，发现还是有问题，这次的问题在文字编码了。<br><br>
<h2>&nbsp;&nbsp; 3、编码问题</h2>
&nbsp;&nbsp;&nbsp; 一般显示不正常的中文pdf都是GBK编码的，mupdf的显示是通过如下两个步骤来做的：<br>&nbsp;&nbsp; 首先解码，将文字内容全部转化成cid，然后将要显示的cid全部push到一个队列，然后遍历cid,将cid转化成gid(对trueType就是转成unicode)，接着显示。<br>mupdf本身有一个比较优雅的办法来解码，通过pdf_lookupcmap来得到unicode，我用了比较笨的办法：自己暴力做GBK到unicode的转换。<br>一般在windows和linux下都有库或者API来完成编码转换问题。不过在PSP下却没有这样的API,只好自己做一个编码转换了，<br>在http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT
找到了转换表，复制粘贴到txt文本，用lua脚本处理下，生成一个.c文件，分别将GBK和unicode值存储到2个数组里，<br>现在你一定知道怎么转换了：二分查找到指定GBK值在GBK数组的下标，然后直接在unicode数组用这个下标，可以得到对应的unicode值。<br>编译测试，OK了，终于能正常显示中文了。<br>不过到现在为止，整个页面只有一种字体，要解决这个问题，我们可以根据名字匹配来找到指定的字体，名字匹配不到的，使用默认的字体（我是用的simsun.ttf）。<br><br>
<h1>&nbsp;txt中文问题</h1>
&nbsp;&nbsp; 相对来说txt的中文问题比较好解决了，基本都是些常规开发，从FzFont.cpp代码可知，txt显示不了中文主要是字体加载的时候，只加载了前面的256个字形。那么我们只要做2件事情就可以显示中文了：<br>&nbsp; 1、文字解码，现在大部分的txt电子书都是gbk编码的，这样比较省空间，解码算法前面已经提过了。<br>&nbsp; 2、中文文字纹理管理和效率问题。一般在PC游戏中，中文字体一般都是将多个连续的汉字按照存储到一张64X64的纹理中，这样可以节省显存，降低渲染批次(3D菜鸟的简单推测)。<br>不过如果在psp也这样做，会发现显示页面是在太慢，最后发现，最简单的办法居然是每个汉字一个纹理，当然要实际用到的时候才生成该汉字纹理。<br>&nbsp; 3、显示页分割。bookr阅读txt的时候，会自己将电子书分割成若干页面，并且支持书签功能，因此，不可避免的涉及到页面分割问题，引入中文显示后，这里稍微有点不同，要注意不能拆分一个汉字，<br>当然，还有其他细节需要处理，这里不多说了。<br><br>
<h1>目录中文问题</h1>
&nbsp; 必须承认，这是我遇到的最痛苦的问题了，原因是从API上就有问题了，读取出来的目录名居然是Shift-jis编码的，谁让PSP是索尼产的呢，我尝试过将PSP的语言设置、时间等本地化设置改成中文、中国等。<br>发现读取到的目录名还是shift-jis编码。我先将目录名从shift-jis转回gb2312，然后显示，结果发现很多汉字丢失，因为从gb2312转到shift-jis的时候已经失真了，转回来显示很多字体就显示不了了。<br>看上去这个问题无法解决了，其实不然，PSP的API提供了打开记忆卡设备的功能，这样，我们自己做一个FAT32驱动（叫驱动不合适，其实就是自己读取FAT32文件系统管理文件）就可以了，FAT32的文档<br>到处都是，linux下也有vfat文件系统的实现，不过我偷懒了，我直接从PMP Player的代码里拷贝了FAT32相关文件，直接移植过来，修改了FzScreenPsp.cpp文件里目录相关的目录读取函数，<br>然后修改目录相关显示代码后，编码显示，一切终于解决了。。。<br><br>&nbsp; <br> <br><br>      <img src ="http://www.cppblog.com/feixuwu/aggbug/121324.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/feixuwu/" target="_blank">feixuwu</a> 2010-07-26 21:41 <a href="http://www.cppblog.com/feixuwu/archive/2010/07/26/121324.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>