Compare commits

...

2 Commits

Author SHA1 Message Date
Flatlogic Bot
62d2f5ab02 f43f43 2025-10-16 21:55:33 +00:00
Flatlogic Bot
61508556c5 final working v01 2025-09-28 21:55:55 +00:00
8 changed files with 29031 additions and 122 deletions

59
assets/css/custom.css Normal file
View File

@ -0,0 +1,59 @@
:root {
--primary-color: #4A90E2;
--secondary-color: #50E3C2;
--background-color: #F4F7F6;
--surface-color: #FFFFFF;
--text-color: #333333;
--border-radius: 0.5rem;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: var(--background-color);
color: var(--text-color);
}
.navbar-brand {
font-weight: 700;
}
.hero {
background: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url('https://picsum.photos/seed/pdf-hero/1200/600');
background-size: cover;
background-position: center;
padding: 6rem 0;
}
.card {
border-radius: var(--border-radius);
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
border: none;
}
.form-control, .form-select {
border-radius: var(--border-radius);
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
border-radius: var(--border-radius);
padding: 0.75rem 1.5rem;
font-weight: 600;
}
.btn-primary:hover {
opacity: 0.9;
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.step-icon {
font-size: 3rem;
color: var(--primary-color);
}
.footer {
background-color: var(--surface-color);
}

14
assets/js/main.js Normal file
View File

@ -0,0 +1,14 @@
document.addEventListener('DOMContentLoaded', function() {
const contactForm = document.getElementById('recolor-form');
if (contactForm) {
contactForm.addEventListener('submit', function(e) {
const pdfFile = document.getElementById('pdfFile').files[0];
if (!pdfFile) {
e.preventDefault(); // Stop submission only if validation fails
alert('Please select a PDF file.');
}
// Allow the form to submit normally if a file is selected
});
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

336
index.php
View File

@ -1,131 +1,237 @@
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
session_start();
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
$downloadLink = null;
$errorMessage = null;
// Function to convert hex color to PDF color components (0-1 range)
function hexToPdfColor($hex) {
$hex = ltrim($hex, '#');
$r = hexdec(substr($hex, 0, 2)) / 255;
$g = hexdec(substr($hex, 2, 2)) / 255;
$b = hexdec(substr($hex, 4, 2)) / 255;
return sprintf('%.3f %.3f %.3f', $r, $g, $b);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Basic check for mutool
$mutoolPath = trim(shell_exec('which mutool'));
if (empty($mutoolPath)) {
$errorMessage = "Error: The required PDF processing tool (mupdf-tools) is not installed on the server. Please contact the administrator.";
} else {
if (isset($_FILES['pdfFile']) && $_FILES['pdfFile']['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $_FILES['pdfFile']['tmp_name'];
$fileType = mime_content_type($fileTmpPath);
if ($fileType === 'application/pdf') {
$uploadsDir = __DIR__ . '/uploads/';
$downloadsDir = __DIR__ . '/downloads/';
$uniqueId = uniqid('pdf_', true);
$originalFileName = $uploadsDir . $uniqueId . '.pdf';
$decompressedFileName = $uploadsDir . $uniqueId . '-decompressed.pdf';
$recoloredFileName = $uploadsDir . $uniqueId . '-recolored.pdf';
$outputFileName = $downloadsDir . $uniqueId . '-final.pdf';
if (move_uploaded_file($fileTmpPath, $originalFileName)) {
$color = $_POST['colorPicker'] ?? '#000000';
$pdfColor = hexToPdfColor($color);
$newColorCommand = $pdfColor . " rg";
$newColorCommandStroke = $pdfColor . " RG";
// 1. Decompress the PDF to make content streams editable
shell_exec(escapeshellcmd("$mutoolPath clean -d " . escapeshellarg($originalFileName) . " " . escapeshellarg($decompressedFileName)));
if (file_exists($decompressedFileName)) {
$content = file_get_contents($decompressedFileName);
// 2. Replace existing color definitions with the new color
// This is a broad approach and might affect non-text elements
// Pattern for RGB color (non-stroking)
$content = preg_replace('/\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+rg/', $newColorCommand, $content);
// Pattern for Grayscale (non-stroking)
$content = preg_replace('/\d*\.?\d+\s+g/', $newColorCommand, $content);
// Pattern for CMYK (non-stroking)
$content = preg_replace('/\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+k/', $newColorCommand, $content);
// Also replace stroking colors to be safe
$content = preg_replace('/\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+RG/', $newColorCommandStroke, $content);
$content = preg_replace('/\d*\.?\d+\s+G/', $newColorCommandStroke, $content);
$content = preg_replace('/\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+\d*\.?\d+\s+K/', $newColorCommandStroke, $content);
file_put_contents($recoloredFileName, $content);
// 3. Re-compress and clean the PDF to fix structure and xref table
shell_exec(escapeshellcmd("$mutoolPath clean " . escapeshellarg($recoloredFileName) . " " . escapeshellarg($outputFileName)));
if (file_exists($outputFileName)) {
$downloadLink = '/downloads/' . basename($outputFileName);
$_SESSION['last_download'] = $downloadLink;
} else {
$errorMessage = "Failed to rebuild the PDF file.";
}
// 4. Clean up temporary files
@unlink($decompressedFileName);
@unlink($recoloredFileName);
@unlink($originalFileName);
} else {
$errorMessage = "Failed to decompress the PDF for editing.";
@unlink($originalFileName);
}
} else {
$errorMessage = "Failed to move uploaded file.";
}
} else {
$errorMessage = "Invalid file type. Please upload a PDF.";
}
} else {
$errorMessage = "File upload failed. Please try again.";
}
}
}
// Check for a download link from a previous successful submission
if (isset($_SESSION['last_download'])) {
$downloadLink = $_SESSION['last_download'];
unset($_SESSION['last_download']);
}
?>
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Text Recolor - Free Online Tool</title>
<meta name="description" content="Free online tool to change the text color of your PDF files. Upload your file, pick a new color, and download the modified PDF instantly.">
<!-- Open Graph / Facebook & Twitter Card Meta Tags -->
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$imageUrl = $protocol . $host . '/assets/pasted-20250928-215140-17dd4a54.png';
$pageUrl = $protocol . $host . $_SERVER['REQUEST_URI'];
?>
<meta property="og:title" content="PDF Text Recolor - Free Online Tool">
<meta property="og:description" content="Free, online tool to change the text color of your PDF files. Upload your file, pick a new color, and download.">
<meta property="og:image" content="<?php echo $imageUrl; ?>">
<meta property="og:url" content="<?php echo $pageUrl; ?>">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="PDF Text Recolor - Free Online Tool">
<meta name="twitter:description" content="Free, online tool to change the text color of your PDF files. Upload your file, pick a new color, and download.">
<meta name="twitter:image" content="<?php echo $imageUrl; ?>">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container">
<a class="navbar-brand" href="/">PDF Text Recolor</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="#how-it-works">How It Works</a></li>
<li class="nav-item"><a class="nav-link" href="/privacy.php">Privacy</a></li>
</ul>
</div>
</div>
</nav>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
<section class="hero text-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-8">
<h1 class="display-4 fw-bold">Recolor Text in Your PDFs, Instantly</h1>
<p class="lead text-muted mb-5">Free, online tool to change the text color of your PDF files. Upload your file, pick a new color, and download.</p>
<div class="card p-4 p-md-5">
<?php if ($errorMessage): ?>
<div class="alert alert-danger">
<?php echo htmlspecialchars($errorMessage); ?>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWiZZy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
<?php endif; ?>
<?php if ($downloadLink): ?>
<div class="alert alert-success text-center">
<h4>Your PDF is ready!</h4>
<p>The text color has been changed. Click the button below to download your file.</p>
<a href="<?php echo htmlspecialchars($downloadLink); ?>" class="btn btn-success btn-lg w-100">
<i class="bi bi-download me-2"></i> Download Your Recicolored PDF
</a>
<hr>
<a href="/" class="btn btn-secondary mt-2">Start Over</a>
</div>
<?php else: ?>
<form id="recolor-form" method="POST" enctype="multipart/form-data">
<div class="mb-3">
<label for="pdfFile" class="form-label fs-5">1. Upload your PDF</label>
<input class="form-control form-control-lg" type="file" id="pdfFile" name="pdfFile" accept=".pdf" required>
</div>
<div class="mb-4">
<label for="colorPicker" class="form-label fs-5">2. Pick a new color</label>
<input type="color" class="form-control form-control-color w-100" id="colorPicker" name="colorPicker" value="#4A90E2" title="Choose your color">
</div>
<button type="submit" class="btn btn-primary btn-lg w-100">Recolor & Download <i class="bi bi-arrow-right-circle ms-2"></i></button>
</form>
<?php endif; ?>
</div>
</div>
</div>
</div>
</section>
<section id="how-it-works" class="py-5">
<div class="container">
<h2 class="text-center mb-5">How It Works</h2>
<div class="row text-center g-4">
<div class="col-md-4">
<div class="card h-100 p-4">
<i class="bi bi-cloud-arrow-up step-icon mb-3"></i>
<h3 class="h4">Upload</h3>
<p class="text-muted">Select the PDF document you want to modify from your device.</p>
<img src="https://picsum.photos/seed/upload-step/400/300" class="img-fluid rounded mt-3" alt="Icon representing uploading a file">
</div>
</div>
<div class="col-md-4">
<div class="card h-100 p-4">
<i class="bi bi-palette step-icon mb-3"></i>
<h3 class="h4">Pick Color</h3>
<p class="text-muted">Choose the new color for the text using the simple color picker.</p>
<img src="https://picsum.photos/seed/color-step/400/300" class="img-fluid rounded mt-3" alt="Icon representing a color palette">
</div>
</div>
<div class="col-md-4">
<div class="card h-100 p-4">
<i class="bi bi-file-earmark-arrow-down step-icon mb-3"></i>
<h3 class="h4">Download</h3>
<p class="text-muted">Your new PDF will be ready for download immediately, with no watermarks.</p>
<img src="https://picsum.photos/seed/download-step/400/300" class="img-fluid rounded mt-3" alt="Icon representing downloading a file">
</div>
</div>
</div>
</div>
</section>
</main>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
<footer class="footer mt-auto py-4 bg-light">
<div class="container text-center">
<p class="text-muted mb-0">&copy; <?php echo date("Y"); ?> PDF Text Recolor. All Rights Reserved. | <a href="/privacy.php" class="text-muted">Privacy Policy</a></p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>

41
privacy.php Normal file
View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Privacy Policy - PDF Text Recolor</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container">
<a class="navbar-brand" href="/">PDF Text Recolor</a>
</div>
</nav>
<main class="container py-5">
<div class="card p-4 p-md-5">
<h1 class="mb-4">Privacy Policy</h1>
<p><strong>This tool is for demonstration purposes only.</strong></p>
<p>We are committed to protecting your privacy. This document serves as a total disclaimer regarding the data you submit to our service.</p>
<h2 class="h4 mt-4">Data Usage and Storage</h2>
<p>We do not store, use, or share any of the files you upload. Your files are processed in memory and are immediately discarded after the text recoloring is complete. No copies are kept.</p>
<h2 class="h4 mt-4">No Guarantees</h2>
<p>This is a simple tool created for fun and to demonstrate a technical capability. We offer no guarantees regarding the functionality or availability of this service.</p>
<a href="/" class="btn btn-primary mt-4">Back to Home</a>
</div>
</main>
<footer class="footer mt-auto py-3">
<div class="container text-center">
<span class="text-muted">&copy; <?php echo date("Y"); ?> PDF Text Recolor. All Rights Reserved.</span>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>