|
|
@@ -0,0 +1,417 @@ |
|
|
|
/* |
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
|
|
* contributor license agreements. See the NOTICE file distributed with |
|
|
|
* this work for additional information regarding copyright ownership. |
|
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
|
|
|
* (the "License"); you may not use this file except in compliance with |
|
|
|
* the License. You may obtain a copy of the License at |
|
|
|
* |
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
* |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* limitations under the License. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* $Id$ */ |
|
|
|
|
|
|
|
package org.apache.fop.pdf; |
|
|
|
|
|
|
|
import java.awt.Dimension; |
|
|
|
import java.awt.Rectangle; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
import java.io.File; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
import static java.util.regex.Pattern.quote; |
|
|
|
|
|
|
|
import javax.xml.transform.stream.StreamResult; |
|
|
|
|
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.runner.RunWith; |
|
|
|
import org.junit.runners.Parameterized; |
|
|
|
import org.junit.runners.Parameterized.Parameters; |
|
|
|
|
|
|
|
import org.apache.fop.apps.FOUserAgent; |
|
|
|
import org.apache.fop.apps.FopFactory; |
|
|
|
import org.apache.fop.fonts.FontInfo; |
|
|
|
import org.apache.fop.render.intermediate.IFContext; |
|
|
|
import org.apache.fop.render.intermediate.IFException; |
|
|
|
import org.apache.fop.render.intermediate.extensions.Link; |
|
|
|
import org.apache.fop.render.intermediate.extensions.URIAction; |
|
|
|
import org.apache.fop.render.pdf.PDFDocumentHandler; |
|
|
|
|
|
|
|
@RunWith(Parameterized.class) |
|
|
|
public class PDFLinkTestCase { |
|
|
|
private String target; |
|
|
|
private String expected; |
|
|
|
|
|
|
|
public PDFLinkTestCase(String target, String expected) { |
|
|
|
this.target = target; |
|
|
|
this.expected = expected; |
|
|
|
} |
|
|
|
|
|
|
|
@Parameters |
|
|
|
public static Collection links() { |
|
|
|
return Arrays.asList(new Object[][] { |
|
|
|
// Windows absolute paths |
|
|
|
{"c:\\foobar.txt", quote("<< /Type /Filespec /F (c:/foobar.txt)")}, //0 |
|
|
|
{"c:\\foo bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, |
|
|
|
{"c:\\foo\\bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"c:\\foo\\bar 2.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// Windows absolute paths using "/" |
|
|
|
{"c:/foo bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, //4 |
|
|
|
{"c:/foo/bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"c:/foo/bar 2.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// Linux absolute paths |
|
|
|
{"/foobar.txt", quote("<< /Type /Filespec /F (/foobar.txt)")}, //7 |
|
|
|
{"/foo/bar.txt", quote("<< /Type /Filespec /F (/foo/bar.txt)")}, |
|
|
|
{"/foo/bar 2.txt", quote("<< /Type /Filespec /F (/foo/bar 2.txt)")}, |
|
|
|
{"/foo bar.txt", quote("<< /Type /Filespec /F (/foo bar.txt)")}, |
|
|
|
|
|
|
|
// Relative paths |
|
|
|
{"foobar.txt", quote("<< /URI (foobar.txt)")}, //11 |
|
|
|
{"foo bar.txt", quote("<< /URI (foo%20bar.txt)")}, |
|
|
|
{"./foobar.txt", quote("<< /URI (./foobar.txt)")}, |
|
|
|
{"./foo bar.txt", quote("<< /URI (./foo%20bar.txt)")}, |
|
|
|
{"../foobar.txt", quote("<< /URI (../foobar.txt)")}, |
|
|
|
{"../foo bar.txt", quote("<< /URI (../foo%20bar.txt)")}, |
|
|
|
|
|
|
|
// Windows network paths |
|
|
|
{"\\\\foo\\bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.txt)")}, //17 |
|
|
|
{"\\\\foo\\bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.txt)")}, |
|
|
|
{"\\\\foo\\a\\bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.txt)")}, |
|
|
|
{"\\\\foo\\a\\bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.txt)")}, |
|
|
|
|
|
|
|
// Windows network path using "/" |
|
|
|
{"//foo/a/bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.txt)")}, // 21 |
|
|
|
{"//foo/a/bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.txt)")}, |
|
|
|
|
|
|
|
// Non ASCII |
|
|
|
// foo bar.txt (unicode) |
|
|
|
{"\uFF46\uFF4F\uFF4F\u3000\uFF42\uFF41\uFF52.txt", quote( |
|
|
|
"<< /URI (%EF%BD%86%EF%BD%8F%EF%BD%8F%E3%80%80%EF%BD%82%EF%BD%81%EF%BD%92.txt)")}, //23 |
|
|
|
// c:/foo/foo bar.txt (unicode) |
|
|
|
{"c:/foo/\uFF46\uFF4F\uFF4F\u3000\uFF42\uFF41\uFF52.txt", quote( |
|
|
|
"<< /Type /Filespec /F " |
|
|
|
+ "<FEFF0063003A002F0066006F006F002FFF46FF4FFF4F3000FF42FF41FF52002E007400780074> " |
|
|
|
+ "/UF <FEFF0063003A002F0066006F006F002FFF46FF4FFF4F3000FF42FF41FF52002E007400780074>")}, |
|
|
|
// \\foo\bar 2\foo bar.txt (unicode) |
|
|
|
{"\\\\foo\\bar 2\\\uFF46\uFF4F\uFF4F\u3000\uFF42\uFF41\uFF52.txt", quote("<< /Type /Filespec /F " |
|
|
|
+ "<FEFF005C005C0066006F006F005C00620061007200200032005CFF46FF4FFF4F3000FF42FF41FF52002E007400780074> " |
|
|
|
+ "/UF " |
|
|
|
+ "<FEFF005C005C0066006F006F005C00620061007200200032005CFF46FF4FFF4F3000FF42FF41FF52002E007400780074>")}, |
|
|
|
|
|
|
|
// PDF, Windows absolute paths |
|
|
|
{"c:\\foobar.pdf", quote("<< /Type /Filespec /F (c:/foobar.pdf)")}, //26 |
|
|
|
{"c:\\foo bar.pdf", quote("<< /Type /Filespec /F (c:/foo bar.pdf)")}, |
|
|
|
{"c:\\foo\\bar.pdf", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)")}, |
|
|
|
{"c:\\foo\\bar 2.pdf", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// PDF, Linux absolute paths |
|
|
|
{"/foobar.pdf", quote("<< /Type /Filespec /F (/foobar.pdf)")}, //30 |
|
|
|
{"/foo bar.pdf", quote("<< /Type /Filespec /F (/foo bar.pdf)")}, |
|
|
|
{"/foo/bar.pdf", quote("<< /Type /Filespec /F (/foo/bar.pdf)")}, |
|
|
|
{"/foo/bar 2.pdf", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// PDF, Relative paths |
|
|
|
{"foobar.pdf", quote("<< /URI (foobar.pdf)")}, //34 |
|
|
|
{"foo bar.pdf", quote("<< /URI (foo%20bar.pdf)")}, |
|
|
|
{"./foobar.pdf", quote("<< /URI (./foobar.pdf)")}, |
|
|
|
{"./foo bar.pdf", quote("<< /URI (./foo%20bar.pdf)")}, |
|
|
|
{"../foobar.pdf", quote("<< /URI (../foobar.pdf)")}, |
|
|
|
{"../foo bar.pdf", quote("<< /URI (../foo%20bar.pdf)")}, |
|
|
|
|
|
|
|
// PDF, Windows network paths |
|
|
|
{"\\\\foo\\bar.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.pdf)")}, //40 |
|
|
|
{"\\\\foo\\bar 2.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.pdf)")}, |
|
|
|
{"\\\\foo\\a\\bar.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.pdf)")}, |
|
|
|
{"\\\\foo\\a\\bar 2.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.pdf)")}, |
|
|
|
|
|
|
|
// PDF with fragments, Windows absolute paths |
|
|
|
{"c:\\foobar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foobar.pdf)") + ".*" + quote("/S /GoToR") + ".*" |
|
|
|
+ quote("/D [ 2 /XYZ null null null ]")}, //44 |
|
|
|
{"c:\\foo bar.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo bar.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D (aa)")}, |
|
|
|
{"c:\\foo\\bar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"c:\\foo\\bar 2.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D (aa)")}, |
|
|
|
|
|
|
|
// PDF with fragments, Windows absolute paths using "/" |
|
|
|
{"c:/foo bar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo bar.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D [ 2 /XYZ null null null ]")}, //48 |
|
|
|
{"c:/foo/bar.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D (aa)")}, |
|
|
|
{"c:/foo/bar 2.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// PDF with fragments, Linux absolute paths |
|
|
|
{"/foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (/foobar.pdf)") + ".*" + quote("/S /GoToR") + ".*" |
|
|
|
+ quote("/D (aa)")}, //51 |
|
|
|
{"/foo/bar.pdf#page=2", quote("<< /Type /Filespec /F (/foo/bar.pdf)") + ".*" + quote("/S /GoToR") + ".*" |
|
|
|
+ quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"/foo/bar 2.pdf#dest=aa", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)") + ".*" + quote("/S /GoToR") |
|
|
|
+ ".*" + quote("/D (aa)")}, |
|
|
|
{"/foo bar.pdf#page=2", quote("<< /Type /Filespec /F (/foo bar.pdf)") + ".*" + quote("/S /GoToR") + ".*" |
|
|
|
+ quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// PDF with fragments, Relative paths |
|
|
|
{"foobar.pdf#dest=aa", quote("<< /URI (foobar.pdf#dest=aa)")}, //55 |
|
|
|
{"foo bar.pdf#page=2", quote("<< /URI (foo%20bar.pdf#page=2)")}, |
|
|
|
{"./foobar.pdf#dest=aa", quote("<< /URI (./foobar.pdf#dest=aa)")}, |
|
|
|
{"./foo bar.pdf#page=2", quote("<< /URI (./foo%20bar.pdf#page=2)")}, |
|
|
|
{"../foobar.pdf#dest=aa", quote("<< /URI (../foobar.pdf#dest=aa)")}, |
|
|
|
{"../foo bar.pdf#page=2", quote("<< /URI (../foo%20bar.pdf#page=2)")}, |
|
|
|
|
|
|
|
// PDF with fragments, Windows network paths |
|
|
|
{"\\\\foo\\bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //61 |
|
|
|
{"\\\\foo\\bar 2.pdf#page=2", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"\\\\foo\\a\\bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"\\\\foo\\a\\bar 2.pdf#page=2", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// file:// prefix, Windows absolute paths |
|
|
|
{"file://c:\\foobar.txt", quote("<< /Type /Filespec /F (c:/foobar.txt)")}, //65 |
|
|
|
{"file://c:\\foo bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, |
|
|
|
{"file://c:\\foo\\bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"file://c:\\foo\\bar 2.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// file:// prefix, Windows absolute paths using "/" |
|
|
|
{"file://c:/foo bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, //69 |
|
|
|
{"file://c:/foo/bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"file://c:/foo/bar 2.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// file:// prefix, Linux absolute paths |
|
|
|
{"file:///foobar.txt", quote("<< /Type /Filespec /F (/foobar.txt)")}, //72 |
|
|
|
{"file:///foo/bar.txt", quote("<< /Type /Filespec /F (/foo/bar.txt)")}, |
|
|
|
{"file:///foo/bar 2.txt", quote("<< /Type /Filespec /F (/foo/bar 2.txt)")}, |
|
|
|
{"file:///foo bar.txt", quote("<< /Type /Filespec /F (/foo bar.txt)")}, |
|
|
|
|
|
|
|
// file:// prefix, Relative paths |
|
|
|
{"file://foobar.txt", quote("<< /Type /Filespec /F (foobar.txt)")}, //76 |
|
|
|
{"file://foo bar.txt", quote("<< /Type /Filespec /F (foo bar.txt)")}, |
|
|
|
{"file://./foobar.txt", quote("<< /Type /Filespec /F (./foobar.txt)")}, |
|
|
|
{"file://./foo bar.txt", quote("<< /Type /Filespec /F (./foo bar.txt)")}, |
|
|
|
{"file://../foobar.txt", quote("<< /Type /Filespec /F (../foobar.txt)")}, |
|
|
|
{"file://../foo bar.txt", quote("<< /Type /Filespec /F (../foo bar.txt)")}, |
|
|
|
|
|
|
|
// file:// prefix, Windows network paths |
|
|
|
{"file://\\\\foo\\bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.txt)")}, //82 |
|
|
|
{"file://\\\\foo\\bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.txt)")}, |
|
|
|
{"file://\\\\foo\\a\\bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.txt)")}, |
|
|
|
{"file://\\\\foo\\a\\bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.txt)")}, |
|
|
|
|
|
|
|
// file:// prefix, Windows network path using "/" |
|
|
|
{"file:////foo/a/bar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.txt)")}, // 86 |
|
|
|
{"file:////foo/a/bar 2.txt", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.txt)")}, |
|
|
|
{"file:////foobar.txt", quote("<< /Type /Filespec /F (\\\\\\\\foobar.txt)")}, |
|
|
|
|
|
|
|
// Proper file:// for windows paths |
|
|
|
{"file:///c:/foo%20bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, //89 |
|
|
|
{"file:///c:/foo/bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"file:///c:/foo/bar%202.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// Proper file:// for linux paths |
|
|
|
{"file:///foo/bar%202.txt", quote("<< /Type /Filespec /F (/foo/bar 2.txt)")}, //92 |
|
|
|
|
|
|
|
// file:// PDF, Windows absolute paths |
|
|
|
{"file://c:\\foobar.pdf", quote("<< /Type /Filespec /F (c:/foobar.pdf)")}, //93 |
|
|
|
{"file://c:\\foo bar.pdf", quote("<< /Type /Filespec /F (c:/foo bar.pdf)")}, |
|
|
|
{"file://c:\\foo\\bar.pdf", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)")}, |
|
|
|
{"file://c:\\foo\\bar 2.pdf", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// file:// PDF, Linux absolute paths |
|
|
|
{"file:///foobar.pdf", quote("<< /Type /Filespec /F (/foobar.pdf)")}, //97 |
|
|
|
{"file:///foo bar.pdf", quote("<< /Type /Filespec /F (/foo bar.pdf)")}, |
|
|
|
{"file:///foo/bar.pdf", quote("<< /Type /Filespec /F (/foo/bar.pdf)")}, |
|
|
|
{"file:///foo/bar 2.pdf", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// file:// PDF, Relative paths |
|
|
|
{"file://foobar.pdf", quote("<< /Type /Filespec /F (foobar.pdf)")}, //101 |
|
|
|
{"file://foo bar.pdf", quote("<< /Type /Filespec /F (foo bar.pdf)")}, |
|
|
|
{"file://./foobar.pdf", quote("<< /Type /Filespec /F (./foobar.pdf)")}, |
|
|
|
{"file://./foo bar.pdf", quote("<< /Type /Filespec /F (./foo bar.pdf)")}, |
|
|
|
{"file://../foobar.pdf", quote("<< /Type /Filespec /F (../foobar.pdf)")}, |
|
|
|
{"file://../foo bar.pdf", quote("<< /Type /Filespec /F (../foo bar.pdf)")}, |
|
|
|
|
|
|
|
// file:// PDF, Windows network paths |
|
|
|
{"file://\\\\foo\\bar.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.pdf)")}, //107 |
|
|
|
{"file://\\\\foo\\bar 2.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.pdf)")}, |
|
|
|
{"file://\\\\foo\\a\\bar.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.pdf)")}, |
|
|
|
{"file://\\\\foo\\a\\bar 2.pdf", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.pdf)")}, |
|
|
|
|
|
|
|
// Proper file:// for windows paths |
|
|
|
{"file:///c:/foo%20bar.pdf", quote("<< /Type /Filespec /F (c:/foo bar.pdf)")}, //111 |
|
|
|
{"file:///c:/foo/bar.pdf", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)")}, |
|
|
|
{"file:///c:/foo/bar%202.pdf", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// Proper file:// PDF, for linux paths |
|
|
|
{"file:///foo/bar%202.pdf", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)")}, //114 |
|
|
|
|
|
|
|
// file:// PDF with fragments, Windows absolute paths |
|
|
|
{"file://c:\\foobar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, //115 |
|
|
|
{"file://c:\\foo bar.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file://c:\\foo\\bar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file://c:\\foo\\bar 2.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
|
|
|
|
// file:// PDF with fragments, Windows absolute paths using "/" |
|
|
|
{"file://c:/foo bar.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, //119 |
|
|
|
{"file://c:/foo/bar.pdf#dest=aa", quote("<< /Type /Filespec /F (c:/foo/bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file://c:/foo/bar 2.pdf#page=2", quote("<< /Type /Filespec /F (c:/foo/bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// file:// PDF with fragments, Linux absolute paths |
|
|
|
{"file:///foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (/foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //122 |
|
|
|
{"file:///foo/bar.pdf#page=2", quote("<< /Type /Filespec /F (/foo/bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file:///foo/bar 2.pdf#dest=aa", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file:///foo bar.pdf#page=2", quote("<< /Type /Filespec /F (/foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// file:// PDF with fragments, Relative paths |
|
|
|
{"file://foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //126 |
|
|
|
{"file://foo bar.pdf#page=2", quote("<< /Type /Filespec /F (foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file://./foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (./foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file://./foo bar.pdf#page=2", quote("<< /Type /Filespec /F (./foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file://../foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (../foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file://../foo bar.pdf#page=2", quote("<< /Type /Filespec /F (../foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// file:// PDF with fragments, Windows network paths |
|
|
|
{"file://\\\\foo\\bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //132 |
|
|
|
{"file://\\\\foo\\bar 2.pdf#page=2", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.pdf)") |
|
|
|
+ ".*" + quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file://\\\\foo\\a\\bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.pdf)") |
|
|
|
+ ".*" + quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file://\\\\foo\\a\\bar 2.pdf#page=2", |
|
|
|
quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// Proper file:// PDF with fragments, Windows network paths |
|
|
|
{"file:////foo/bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //136 |
|
|
|
{"file:////foo/bar%202.pdf#page=2", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file:////foo/a/bar.pdf#dest=aa", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar.pdf)") |
|
|
|
+ ".*" + quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file:////foo/a/bar%202.pdf#page=2", quote("<< /Type /Filespec /F (\\\\\\\\foo\\\\a\\\\bar 2.pdf)") |
|
|
|
+ ".*" + quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// Proper file:// PDF, for linux paths |
|
|
|
{"file:///foo/bar%202.pdf#page=2", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, //140 |
|
|
|
|
|
|
|
// file: Relative paths |
|
|
|
{"file:foobar.txt", quote("<< /Type /Filespec /F (foobar.txt)")}, //141 |
|
|
|
{"file:foo bar.txt", quote("<< /Type /Filespec /F (foo bar.txt)")}, |
|
|
|
{"file:./foobar.txt", quote("<< /Type /Filespec /F (./foobar.txt)")}, |
|
|
|
{"file:./foo bar.txt", quote("<< /Type /Filespec /F (./foo bar.txt)")}, |
|
|
|
{"file:../foobar.txt", quote("<< /Type /Filespec /F (../foobar.txt)")}, |
|
|
|
{"file:../foo bar.txt", quote("<< /Type /Filespec /F (../foo bar.txt)")}, |
|
|
|
{"file:\uFF46\uFF4F\uFF4F\u3000\uFF42\uFF41\uFF52.txt", |
|
|
|
quote("<< /Type /Filespec /F <FEFFFF46FF4FFF4F3000FF42FF41FF52002E007400780074> " |
|
|
|
+ "/UF <FEFFFF46FF4FFF4F3000FF42FF41FF52002E007400780074>")}, |
|
|
|
|
|
|
|
// file: PDF Relative paths |
|
|
|
{"file:foobar.pdf", quote("<< /Type /Filespec /F (foobar.pdf)")}, //148 |
|
|
|
{"file:foo bar.pdf", quote("<< /Type /Filespec /F (foo bar.pdf)")}, |
|
|
|
{"file:./foobar.pdf", quote("<< /Type /Filespec /F (./foobar.pdf)")}, |
|
|
|
{"file:./foo bar.pdf", quote("<< /Type /Filespec /F (./foo bar.pdf)")}, |
|
|
|
{"file:../foobar.pdf", quote("<< /Type /Filespec /F (../foobar.pdf)")}, |
|
|
|
{"file:../foo bar.pdf", quote("<< /Type /Filespec /F (../foo bar.pdf)")}, |
|
|
|
|
|
|
|
// file: PDF with fragments, Relative paths |
|
|
|
{"file:foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, //154 |
|
|
|
{"file:foo bar.pdf#page=2", quote("<< /Type /Filespec /F (foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file:./foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (./foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file:./foo bar.pdf#page=2", quote("<< /Type /Filespec /F (./foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
{"file:../foobar.pdf#dest=aa", quote("<< /Type /Filespec /F (../foobar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D (aa)")}, |
|
|
|
{"file:../foo bar.pdf#page=2", quote("<< /Type /Filespec /F (../foo bar.pdf)") + ".*" |
|
|
|
+ quote("/S /GoToR") + ".*" + quote("/D [ 2 /XYZ null null null ]")}, |
|
|
|
|
|
|
|
// file: prefix, Windows absolute paths |
|
|
|
{"file:c:\\foobar.txt", quote("<< /Type /Filespec /F (c:/foobar.txt)")}, //160 |
|
|
|
{"file:c:\\foo bar.txt", quote("<< /Type /Filespec /F (c:/foo bar.txt)")}, |
|
|
|
{"file:c:\\foo\\bar.txt", quote("<< /Type /Filespec /F (c:/foo/bar.txt)")}, |
|
|
|
{"file:c:\\foo\\bar 2.txt", quote("<< /Type /Filespec /F (c:/foo/bar 2.txt)")}, |
|
|
|
|
|
|
|
// PDF, Linux absolute paths |
|
|
|
{"file:/foobar.pdf", quote("<< /Type /Filespec /F (/foobar.pdf)")}, //164 |
|
|
|
{"file:/foo bar.pdf", quote("<< /Type /Filespec /F (/foo bar.pdf)")}, |
|
|
|
{"file:/foo%20bar.pdf", quote("<< /Type /Filespec /F (/foo bar.pdf)")}, |
|
|
|
{"file:/foo/bar.pdf", quote("<< /Type /Filespec /F (/foo/bar.pdf)")}, |
|
|
|
{"file:/foo/bar 2.pdf", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)")}, |
|
|
|
{"file:/foo/bar%202.pdf", quote("<< /Type /Filespec /F (/foo/bar 2.pdf)")}, |
|
|
|
|
|
|
|
// Web links |
|
|
|
{"https://xmlgraphics.apache.org/fop/", quote("<< /URI (https://xmlgraphics.apache.org/fop/)")}, //170 |
|
|
|
{"http://xmlgraphics.apache.org/fop/", quote("<< /URI (http://xmlgraphics.apache.org/fop/)")}, |
|
|
|
{"https://xmlgraphics.apache.org/fop/examples.html", |
|
|
|
quote("<< /URI (https://xmlgraphics.apache.org/fop/examples.html)")}, |
|
|
|
{"https://xmlgraphics.apache.org/fop/fo/fonts.fo.pdf", |
|
|
|
quote("<< /URI (https://xmlgraphics.apache.org/fop/fo/fonts.fo.pdf)")}, |
|
|
|
{"https://xmlgraphics.apache.org/fop/fo/fonts.fo.pdf#page=2", |
|
|
|
quote("<< /URI (https://xmlgraphics.apache.org/fop/fo/fonts.fo.pdf#page=2)")}, |
|
|
|
{"https://xmlgraphics.apache.org/fop/fo/fonts.fo", |
|
|
|
quote("<< /URI (https://xmlgraphics.apache.org/fop/fo/fonts.fo)")}, |
|
|
|
|
|
|
|
// HTML files |
|
|
|
{"examples.html#foo", quote("<< /URI (examples.html#foo)")}, //177 |
|
|
|
{"examples.html?foo#bar", quote("/URI (examples.html?foo#bar)")}, |
|
|
|
{"examples.html", quote("<< /URI (examples.html)")}, |
|
|
|
{"file:examples.html", quote("<< /Type /Filespec /F (examples.html)")}, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void testLinks() throws IFException { |
|
|
|
FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent(); |
|
|
|
PDFDocumentHandler docHandler = new PDFDocumentHandler(new IFContext(ua)); |
|
|
|
docHandler.setFontInfo(new FontInfo()); |
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
|
|
|
docHandler.setResult(new StreamResult(out)); |
|
|
|
docHandler.startDocument(); |
|
|
|
docHandler.startPage(0, "", "", new Dimension()); |
|
|
|
docHandler.getDocumentNavigationHandler().renderLink(new Link( |
|
|
|
new URIAction(target, false), new Rectangle())); |
|
|
|
docHandler.endDocument(); |
|
|
|
|
|
|
|
// Normalize spaces between word for easier testing |
|
|
|
String outString = out.toString().replaceAll("\\s+", " "); |
|
|
|
|
|
|
|
Pattern r = Pattern.compile(expected); |
|
|
|
Matcher m = r.matcher(outString); |
|
|
|
Assert.assertTrue(m.find()); |
|
|
|
} |
|
|
|
} |